|
//------------------------------------------------------------------------------
// <copyright file="SmiMetaData.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">Microsoft</owner>
// <owner current="true" primary="false">Microsoft</owner>
//------------------------------------------------------------------------------
namespace Microsoft.SqlServer.Server {
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Data;
using System.Data.Sql;
using System.Data.SqlTypes;
using System.Globalization;
// DESIGN NOTES
//
// The following classes are a tight inheritance heirarchy, and are not designed for
// being inherited outside of this file. Instances are guaranteed to be immutable, and
// outside classes rely on this fact.
//
// The various levels may not all be used outside of this file, but for clarity of purpose
// they are all usefull distinctions to make.
//
// In general, moving lower in the type heirarchy exposes less portable values. Thus,
// the root metadata can be readily shared across different (MSSQL) servers and clients,
// while QueryMetaData has attributes tied to a specific query, running against specific
// data storage on a specific server.
//
// The SmiMetaData heirarchy does not do data validation on retail builds! It will assert
// that the values passed to it have been validated externally, however.
//
// SmiMetaData
//
// Root of the heirarchy.
// Represents the minimal amount of metadata required to represent any Sql Server datum
// without any references to any particular server or schema (thus, no server-specific multi-part names).
// It could be used to communicate solely between two disconnected clients, for instance.
//
// NOTE: It currently does not contain sufficient information to describe typed XML, since we
// don't have a good server-independent mechanism for such.
//
// This class is also used as implementation for the public SqlMetaData class.
internal class SmiMetaData {
private SqlDbType _databaseType; // Main enum that determines what is valid for other attributes.
private long _maxLength; // Varies for variable-length types, others are fixed value per type
private byte _precision; // Varies for SqlDbType.Decimal, others are fixed value per type
private byte _scale; // Varies for SqlDbType.Decimal, others are fixed value per type
private long _localeId; // Valid only for character types, others are 0
private SqlCompareOptions _compareOptions; // Valid only for character types, others are SqlCompareOptions.Default
private Type _clrType; // Varies for SqlDbType.Udt, others are fixed value per type.
private string _udtAssemblyQualifiedName; // Valid only for UDT types when _clrType is not available
private bool _isMultiValued; // Multiple instances per value? (I.e. tables, arrays)
private IList<SmiExtendedMetaData> _fieldMetaData; // Metadata of fields for structured types
private SmiMetaDataPropertyCollection _extendedProperties; // Extended properties, Key columns, sort order, etc.
// DevNote: For now, since the list of extended property types is small, we can handle them in a simple list.
// In the future, we may need to create a more performant storage & lookup mechanism, such as a hash table
// of lists indexed by type of property or an array of lists with a well-known index for each type.
// Limits for attributes (SmiMetaData will assert that these limits as applicable in constructor)
internal const long UnlimitedMaxLengthIndicator = -1; // unlimited (except by implementation) max-length.
internal const long MaxUnicodeCharacters = 4000; // Maximum for limited type
internal const long MaxANSICharacters = 8000; // Maximum for limited type
internal const long MaxBinaryLength = 8000; // Maximum for limited type
internal const int MinPrecision = 1; // SqlDecimal defines max precision
internal const int MinScale = 0; // SqlDecimal defines max scale
internal const int MaxTimeScale = 7; // Max scale for time, datetime2, and datetimeoffset
internal static readonly DateTime MaxSmallDateTime = new DateTime(2079, 06, 06, 23, 59, 29, 998);
internal static readonly DateTime MinSmallDateTime = new DateTime(1899, 12, 31, 23, 59, 29, 999);
internal static readonly SqlMoney MaxSmallMoney = new SqlMoney( ( (Decimal)Int32.MaxValue ) / 10000 );
internal static readonly SqlMoney MinSmallMoney = new SqlMoney( ( (Decimal)Int32.MinValue ) / 10000 );
internal const SqlCompareOptions DefaultStringCompareOptions = SqlCompareOptions.IgnoreCase
| SqlCompareOptions.IgnoreKanaType | SqlCompareOptions.IgnoreWidth;
internal const long MaxNameLength = 128; // maximum length in the server is 128.
private static readonly IList<SmiExtendedMetaData> __emptyFieldList = new List<SmiExtendedMetaData>().AsReadOnly();
// Precision to max length lookup table
private static byte[] __maxLenFromPrecision = new byte[] {5,5,5,5,5,5,5,5,5,9,9,9,9,9,
9,9,9,9,9,13,13,13,13,13,13,13,13,13,17,17,17,17,17,17,17,17,17,17};
// Scale offset to max length lookup table
private static byte[] __maxVarTimeLenOffsetFromScale = new byte[] { 2, 2, 2, 1, 1, 0, 0, 0 };
// Defaults
// SmiMetaData(SqlDbType, MaxLen, Prec, Scale, CompareOptions)
internal static readonly SmiMetaData DefaultBigInt = new SmiMetaData(SqlDbType.BigInt, 8, 19, 0, SqlCompareOptions.None); // SqlDbType.BigInt
internal static readonly SmiMetaData DefaultBinary = new SmiMetaData(SqlDbType.Binary, 1, 0, 0, SqlCompareOptions.None); // SqlDbType.Binary
internal static readonly SmiMetaData DefaultBit = new SmiMetaData(SqlDbType.Bit, 1, 1, 0, SqlCompareOptions.None); // SqlDbType.Bit
internal static readonly SmiMetaData DefaultChar_NoCollation = new SmiMetaData(SqlDbType.Char, 1, 0, 0, DefaultStringCompareOptions);// SqlDbType.Char
internal static readonly SmiMetaData DefaultDateTime = new SmiMetaData(SqlDbType.DateTime, 8, 23, 3, SqlCompareOptions.None); // SqlDbType.DateTime
internal static readonly SmiMetaData DefaultDecimal = new SmiMetaData(SqlDbType.Decimal, 9, 18, 0, SqlCompareOptions.None); // SqlDbType.Decimal
internal static readonly SmiMetaData DefaultFloat = new SmiMetaData(SqlDbType.Float, 8, 53, 0, SqlCompareOptions.None); // SqlDbType.Float
internal static readonly SmiMetaData DefaultImage = new SmiMetaData(SqlDbType.Image, UnlimitedMaxLengthIndicator,0, 0, SqlCompareOptions.None); // SqlDbType.Image
internal static readonly SmiMetaData DefaultInt = new SmiMetaData(SqlDbType.Int, 4, 10, 0, SqlCompareOptions.None); // SqlDbType.Int
internal static readonly SmiMetaData DefaultMoney = new SmiMetaData(SqlDbType.Money, 8, 19, 4, SqlCompareOptions.None); // SqlDbType.Money
internal static readonly SmiMetaData DefaultNChar_NoCollation = new SmiMetaData(SqlDbType.NChar, 1, 0, 0, DefaultStringCompareOptions);// SqlDbType.NChar
internal static readonly SmiMetaData DefaultNText_NoCollation = new SmiMetaData(SqlDbType.NText, UnlimitedMaxLengthIndicator,0, 0, DefaultStringCompareOptions);// SqlDbType.NText
internal static readonly SmiMetaData DefaultNVarChar_NoCollation = new SmiMetaData(SqlDbType.NVarChar, MaxUnicodeCharacters, 0, 0, DefaultStringCompareOptions);// SqlDbType.NVarChar
internal static readonly SmiMetaData DefaultReal = new SmiMetaData(SqlDbType.Real, 4, 24, 0, SqlCompareOptions.None); // SqlDbType.Real
internal static readonly SmiMetaData DefaultUniqueIdentifier = new SmiMetaData(SqlDbType.UniqueIdentifier, 16, 0, 0, SqlCompareOptions.None); // SqlDbType.UniqueIdentifier
internal static readonly SmiMetaData DefaultSmallDateTime = new SmiMetaData(SqlDbType.SmallDateTime, 4, 16, 0, SqlCompareOptions.None); // SqlDbType.SmallDateTime
internal static readonly SmiMetaData DefaultSmallInt = new SmiMetaData(SqlDbType.SmallInt, 2, 5, 0, SqlCompareOptions.None); // SqlDbType.SmallInt
internal static readonly SmiMetaData DefaultSmallMoney = new SmiMetaData(SqlDbType.SmallMoney, 4, 10, 4, SqlCompareOptions.None); // SqlDbType.SmallMoney
internal static readonly SmiMetaData DefaultText_NoCollation = new SmiMetaData(SqlDbType.Text, UnlimitedMaxLengthIndicator,0, 0, DefaultStringCompareOptions);// SqlDbType.Text
internal static readonly SmiMetaData DefaultTimestamp = new SmiMetaData(SqlDbType.Timestamp, 8, 0, 0, SqlCompareOptions.None); // SqlDbType.Timestamp
internal static readonly SmiMetaData DefaultTinyInt = new SmiMetaData(SqlDbType.TinyInt, 1, 3, 0, SqlCompareOptions.None); // SqlDbType.TinyInt
internal static readonly SmiMetaData DefaultVarBinary = new SmiMetaData(SqlDbType.VarBinary, MaxBinaryLength, 0, 0, SqlCompareOptions.None); // SqlDbType.VarBinary
internal static readonly SmiMetaData DefaultVarChar_NoCollation = new SmiMetaData(SqlDbType.VarChar, MaxANSICharacters, 0, 0, DefaultStringCompareOptions);// SqlDbType.VarChar
internal static readonly SmiMetaData DefaultVariant = new SmiMetaData(SqlDbType.Variant, 8016, 0, 0, SqlCompareOptions.None); // SqlDbType.Variant
internal static readonly SmiMetaData DefaultXml = new SmiMetaData(SqlDbType.Xml, UnlimitedMaxLengthIndicator,0, 0, DefaultStringCompareOptions);// SqlDbType.Xml
internal static readonly SmiMetaData DefaultUdt_NoType = new SmiMetaData(SqlDbType.Udt, 0, 0, 0, SqlCompareOptions.None); // SqlDbType.Udt
internal static readonly SmiMetaData DefaultStructured = new SmiMetaData(SqlDbType.Structured, 0, 0, 0, SqlCompareOptions.None); // SqlDbType.Structured
internal static readonly SmiMetaData DefaultDate = new SmiMetaData(SqlDbType.Date, 3, 10, 0, SqlCompareOptions.None); // SqlDbType.Date
internal static readonly SmiMetaData DefaultTime = new SmiMetaData(SqlDbType.Time, 5, 0, 7, SqlCompareOptions.None); // SqlDbType.Time
internal static readonly SmiMetaData DefaultDateTime2 = new SmiMetaData(SqlDbType.DateTime2, 8, 0, 7, SqlCompareOptions.None); // SqlDbType.DateTime2
internal static readonly SmiMetaData DefaultDateTimeOffset = new SmiMetaData(SqlDbType.DateTimeOffset, 10, 0, 7, SqlCompareOptions.None); // SqlDbType.DateTimeOffset
// No default for generic UDT
// character defaults hook thread-local culture to get collation
internal static SmiMetaData DefaultChar {
get {
return new SmiMetaData(
DefaultChar_NoCollation.SqlDbType,
DefaultChar_NoCollation.MaxLength,
DefaultChar_NoCollation.Precision,
DefaultChar_NoCollation.Scale,
System.Globalization.CultureInfo.CurrentCulture.LCID,
SqlCompareOptions.IgnoreCase | SqlCompareOptions.IgnoreKanaType | SqlCompareOptions.IgnoreWidth,
null
);
}
}
internal static SmiMetaData DefaultNChar {
get {
return new SmiMetaData(
DefaultNChar_NoCollation.SqlDbType,
DefaultNChar_NoCollation.MaxLength,
DefaultNChar_NoCollation.Precision,
DefaultNChar_NoCollation.Scale,
System.Globalization.CultureInfo.CurrentCulture.LCID,
SqlCompareOptions.IgnoreCase | SqlCompareOptions.IgnoreKanaType | SqlCompareOptions.IgnoreWidth,
null
);
}
}
internal static SmiMetaData DefaultNText {
get {
return new SmiMetaData(
DefaultNText_NoCollation.SqlDbType,
DefaultNText_NoCollation.MaxLength,
DefaultNText_NoCollation.Precision,
DefaultNText_NoCollation.Scale,
System.Globalization.CultureInfo.CurrentCulture.LCID,
SqlCompareOptions.IgnoreCase | SqlCompareOptions.IgnoreKanaType | SqlCompareOptions.IgnoreWidth,
null
);
}
}
internal static SmiMetaData DefaultNVarChar {
get {
return new SmiMetaData(
DefaultNVarChar_NoCollation.SqlDbType,
DefaultNVarChar_NoCollation.MaxLength,
DefaultNVarChar_NoCollation.Precision,
DefaultNVarChar_NoCollation.Scale,
System.Globalization.CultureInfo.CurrentCulture.LCID,
SqlCompareOptions.IgnoreCase | SqlCompareOptions.IgnoreKanaType | SqlCompareOptions.IgnoreWidth,
null
);
}
}
internal static SmiMetaData DefaultText {
get {
return new SmiMetaData(
DefaultText_NoCollation.SqlDbType,
DefaultText_NoCollation.MaxLength,
DefaultText_NoCollation.Precision,
DefaultText_NoCollation.Scale,
System.Globalization.CultureInfo.CurrentCulture.LCID,
SqlCompareOptions.IgnoreCase | SqlCompareOptions.IgnoreKanaType | SqlCompareOptions.IgnoreWidth,
null
);
}
}
internal static SmiMetaData DefaultVarChar {
get {
return new SmiMetaData(
DefaultVarChar_NoCollation.SqlDbType,
DefaultVarChar_NoCollation.MaxLength,
DefaultVarChar_NoCollation.Precision,
DefaultVarChar_NoCollation.Scale,
System.Globalization.CultureInfo.CurrentCulture.LCID,
SqlCompareOptions.IgnoreCase | SqlCompareOptions.IgnoreKanaType | SqlCompareOptions.IgnoreWidth,
null
);
}
}
// The one and only constructor for use by outside code.
//
// Parameters that matter for given values of dbType (other parameters are ignored in favor of internal defaults).
// Thus, if dbType parameter value is SqlDbType.Decimal, the values of precision and scale passed in are used, but
// maxLength, localeId, compareOptions, etc are set to defaults for the Decimal type:
// SqlDbType.BigInt: dbType
// SqlDbType.Binary: dbType, maxLength
// SqlDbType.Bit: dbType
// SqlDbType.Char: dbType, maxLength, localeId, compareOptions
// SqlDbType.DateTime: dbType
// SqlDbType.Decimal: dbType, precision, scale
// SqlDbType.Float: dbType
// SqlDbType.Image: dbType
// SqlDbType.Int: dbType
// SqlDbType.Money: dbType
// SqlDbType.NChar: dbType, maxLength, localeId, compareOptions
// SqlDbType.NText: dbType, localeId, compareOptions
// SqlDbType.NVarChar: dbType, maxLength, localeId, compareOptions
// SqlDbType.Real: dbType
// SqlDbType.UniqueIdentifier: dbType
// SqlDbType.SmallDateTime: dbType
// SqlDbType.SmallInt: dbType
// SqlDbType.SmallMoney: dbType
// SqlDbType.Text: dbType, localeId, compareOptions
// SqlDbType.Timestamp: dbType
// SqlDbType.TinyInt: dbType
// SqlDbType.VarBinary: dbType, maxLength
// SqlDbType.VarChar: dbType, maxLength, localeId, compareOptions
// SqlDbType.Variant: dbType
// PlaceHolder for value 24
// SqlDbType.Xml: dbType
// Placeholder for value 26
// Placeholder for value 27
// Placeholder for value 28
// SqlDbType.Udt: dbType, userDefinedType
//
[ObsoleteAttribute( "Not supported as of SMI v2. Will be removed when v1 support dropped. Use ctor without columns param." )]
internal SmiMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
SmiMetaData[] columns) :
// Implement as calling the new ctor
this(
dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType ) {
Debug.Assert( null == columns, "Row types not supported" );
}
// SMI V100 (aka V3) constructor. Superceded in V200.
internal SmiMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType) :
this( dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
false,
null,
null ) {
}
// SMI V200 ctor.
internal SmiMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
bool isMultiValued,
IList<SmiExtendedMetaData> fieldTypes,
SmiMetaDataPropertyCollection extendedProperties)
:
this(dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
null,
isMultiValued,
fieldTypes,
extendedProperties) {
}
// SMI V220 ctor.
internal SmiMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
string udtAssemblyQualifiedName,
bool isMultiValued,
IList<SmiExtendedMetaData> fieldTypes,
SmiMetaDataPropertyCollection extendedProperties) {
Debug.Assert( IsSupportedDbType(dbType), "Invalid SqlDbType: " + dbType );
SetDefaultsForType( dbType );
//
switch ( dbType ) {
case SqlDbType.BigInt:
case SqlDbType.Bit:
case SqlDbType.DateTime:
case SqlDbType.Float:
case SqlDbType.Image:
case SqlDbType.Int:
case SqlDbType.Money:
case SqlDbType.Real:
case SqlDbType.SmallDateTime:
case SqlDbType.SmallInt:
case SqlDbType.SmallMoney:
case SqlDbType.Timestamp:
case SqlDbType.TinyInt:
case SqlDbType.UniqueIdentifier:
case SqlDbType.Variant:
case SqlDbType.Xml:
case SqlDbType.Date:
break;
case SqlDbType.Binary:
case SqlDbType.VarBinary:
_maxLength = maxLength;
break;
case SqlDbType.Char:
case SqlDbType.NChar:
case SqlDbType.NVarChar:
case SqlDbType.VarChar:
// locale and compare options are not validated until they get to the server
_maxLength = maxLength;
_localeId = localeId;
_compareOptions = compareOptions;
break;
case SqlDbType.NText:
case SqlDbType.Text:
_localeId = localeId;
_compareOptions = compareOptions;
break;
case SqlDbType.Decimal:
Debug.Assert( MinPrecision <= precision && SqlDecimal.MaxPrecision >= precision, "Invalid precision: " + precision );
Debug.Assert( MinScale <= scale && SqlDecimal.MaxScale >= scale, "Invalid scale: " + scale );
Debug.Assert( scale <= precision, "Precision: " + precision + " greater than scale: " + scale );
_precision = precision;
_scale = scale;
_maxLength = __maxLenFromPrecision[precision - 1];
break;
case SqlDbType.Udt:
// Assert modified for VSFTDEVDIV479492 - for SqlParameter both userDefinedType and udtAssemblyQualifiedName
// can be NULL, we are checking only maxLength if it will be used (i.e. userDefinedType is NULL)
Debug.Assert((null != userDefinedType) || (0 <= maxLength || UnlimitedMaxLengthIndicator == maxLength),
String.Format((IFormatProvider)null, "SmiMetaData.ctor: Udt name={0}, maxLength={1}", udtAssemblyQualifiedName, maxLength));
// Type not validated until matched to a server. Could be null if extended metadata supplies three-part name!
_clrType = userDefinedType;
if (null != userDefinedType) {
_maxLength = SerializationHelperSql9.GetUdtMaxLength(userDefinedType);
}
else {
_maxLength = maxLength;
}
_udtAssemblyQualifiedName = udtAssemblyQualifiedName;
break;
case SqlDbType.Structured:
if (null != fieldTypes) {
_fieldMetaData = (new List<SmiExtendedMetaData>(fieldTypes)).AsReadOnly();
}
_isMultiValued = isMultiValued;
_maxLength = _fieldMetaData.Count;
break;
case SqlDbType.Time:
Debug.Assert(MinScale <= scale && scale <= MaxTimeScale, "Invalid time scale: " + scale);
_scale = scale;
_maxLength = 5 - __maxVarTimeLenOffsetFromScale[scale];
break;
case SqlDbType.DateTime2:
Debug.Assert(MinScale <= scale && scale <= MaxTimeScale, "Invalid time scale: " + scale);
_scale = scale;
_maxLength = 8 - __maxVarTimeLenOffsetFromScale[scale];
break;
case SqlDbType.DateTimeOffset:
Debug.Assert(MinScale <= scale && scale <= MaxTimeScale, "Invalid time scale: " + scale);
_scale = scale;
_maxLength = 10 - __maxVarTimeLenOffsetFromScale[scale];
break;
default:
Debug.Assert( false, "How in the world did we get here? :" + dbType );
break;
}
if (null != extendedProperties) {
extendedProperties.SetReadOnly();
_extendedProperties = extendedProperties;
}
// properties and fields must meet the following conditions at this point:
// 1) not null
// 2) read only
// 3) same number of columns in each list (0 count acceptable for properties that are "unused")
Debug.Assert(null != _extendedProperties && _extendedProperties.IsReadOnly, "SmiMetaData.ctor: _extendedProperties is " + (null!=_extendedProperties?"writeable":"null"));
Debug.Assert(null != _fieldMetaData && _fieldMetaData.IsReadOnly, "SmiMetaData.ctor: _fieldMetaData is " + (null!=_fieldMetaData?"writeable":"null"));
#if DEBUG
((SmiDefaultFieldsProperty)_extendedProperties[SmiPropertySelector.DefaultFields]).CheckCount(_fieldMetaData.Count);
((SmiOrderProperty)_extendedProperties[SmiPropertySelector.SortOrder]).CheckCount(_fieldMetaData.Count);
((SmiUniqueKeyProperty)_extendedProperties[SmiPropertySelector.UniqueKey]).CheckCount(_fieldMetaData.Count);
#endif
}
internal bool IsValidMaxLengthForCtorGivenType( SqlDbType dbType, long maxLength ) {
bool result = true;
switch( dbType ) {
case SqlDbType.BigInt:
case SqlDbType.Bit:
case SqlDbType.DateTime:
case SqlDbType.Float:
case SqlDbType.Image:
case SqlDbType.Int:
case SqlDbType.Money:
case SqlDbType.Real:
case SqlDbType.SmallDateTime:
case SqlDbType.SmallInt:
case SqlDbType.SmallMoney:
case SqlDbType.Timestamp:
case SqlDbType.TinyInt:
case SqlDbType.UniqueIdentifier:
case SqlDbType.Variant:
case SqlDbType.Xml:
case SqlDbType.NText:
case SqlDbType.Text:
case SqlDbType.Decimal:
case SqlDbType.Udt:
case SqlDbType.Structured: //
case SqlDbType.Date:
case SqlDbType.Time:
case SqlDbType.DateTime2:
case SqlDbType.DateTimeOffset:
break;
case SqlDbType.Binary:
result = 0 < maxLength && MaxBinaryLength >= maxLength;
break;
case SqlDbType.VarBinary:
result = UnlimitedMaxLengthIndicator == maxLength || ( 0 < maxLength && MaxBinaryLength >= maxLength );
break;
case SqlDbType.Char:
result = 0 < maxLength && MaxANSICharacters >= maxLength;
break;
case SqlDbType.NChar:
result = 0 < maxLength && MaxUnicodeCharacters >= maxLength;
break;
case SqlDbType.NVarChar:
result = UnlimitedMaxLengthIndicator == maxLength || ( 0 < maxLength && MaxUnicodeCharacters >= maxLength );
break;
case SqlDbType.VarChar:
result = UnlimitedMaxLengthIndicator == maxLength || ( 0 < maxLength && MaxANSICharacters >= maxLength );
break;
default:
Debug.Assert( false, "How in the world did we get here? :" + dbType );
break;
}
return result;
}
// Sql-style compare options for character types.
internal SqlCompareOptions CompareOptions {
get {
return _compareOptions;
}
}
// LCID for type. 0 for non-character types.
internal long LocaleId {
get{
return _localeId;
}
}
// Units of length depend on type.
// NVarChar, NChar, NText: # of unicode characters
// Everything else: # of bytes
internal long MaxLength {
get {
return _maxLength;
}
}
internal byte Precision {
get {
return _precision;
}
}
internal byte Scale {
get {
return _scale;
}
}
internal SqlDbType SqlDbType {
get {
return _databaseType;
}
}
// Clr Type instance for user-defined types
internal Type Type {
get {
// Fault-in UDT clr types on access if have assembly-qualified name
if (null == _clrType && SqlDbType.Udt == _databaseType && _udtAssemblyQualifiedName != null) {
_clrType = Type.GetType(_udtAssemblyQualifiedName, true);
}
return _clrType;
}
}
// Clr Type instance for user-defined types in cases where we don't want to throw if the assembly isn't available
internal Type TypeWithoutThrowing {
get {
// Fault-in UDT clr types on access if have assembly-qualified name
if (null == _clrType && SqlDbType.Udt == _databaseType && _udtAssemblyQualifiedName != null) {
_clrType = Type.GetType(_udtAssemblyQualifiedName, false);
}
return _clrType;
}
}
internal string TypeName {
get {
string result = null;
if (SqlDbType.Udt == _databaseType) {
Debug.Assert(String.Empty == __typeNameByDatabaseType[(int)_databaseType], "unexpected udt?");
result = Type.FullName;
}
else {
result = __typeNameByDatabaseType[(int)_databaseType];
Debug.Assert(null != result, "unknown type name?");
}
return result;
}
}
internal string AssemblyQualifiedName {
get {
string result = null;
if (SqlDbType.Udt == _databaseType) {
// Fault-in assembly-qualified name if type is available
if (_udtAssemblyQualifiedName == null && _clrType != null) {
_udtAssemblyQualifiedName = _clrType.AssemblyQualifiedName;
}
result = _udtAssemblyQualifiedName;
}
return result;
}
}
internal bool IsMultiValued {
get {
return _isMultiValued;
}
}
// Returns read-only list of field metadata
internal IList<SmiExtendedMetaData> FieldMetaData {
get {
return _fieldMetaData;
}
}
// Returns read-only list of extended properties
internal SmiMetaDataPropertyCollection ExtendedProperties {
get {
return _extendedProperties;
}
}
internal static bool IsSupportedDbType(SqlDbType dbType) {
// Hole in SqlDbTypes between Xml and Udt for non-WinFS scenarios.
return (SqlDbType.BigInt <= dbType && SqlDbType.Xml >= dbType) ||
(SqlDbType.Udt <= dbType && SqlDbType.DateTimeOffset >= dbType);
}
// Only correct access point for defaults per SqlDbType.
internal static SmiMetaData GetDefaultForType( SqlDbType dbType ) {
Debug.Assert( IsSupportedDbType(dbType), "Unsupported SqlDbtype: " + dbType);
return __defaultValues[(int)dbType];
}
// Private constructor used only to initialize default instance array elements.
// DO NOT EXPOSE OUTSIDE THIS CLASS!
private SmiMetaData (
SqlDbType sqlDbType,
long maxLength,
byte precision,
byte scale,
SqlCompareOptions compareOptions) {
_databaseType = sqlDbType;
_maxLength = maxLength;
_precision = precision;
_scale = scale;
_compareOptions = compareOptions;
// defaults are the same for all types for the following attributes.
_localeId = 0;
_clrType = null;
_isMultiValued = false;
_fieldMetaData = __emptyFieldList;
_extendedProperties = SmiMetaDataPropertyCollection.EmptyInstance;
}
// static array of default-valued metadata ordered by corresponding SqlDbType.
// NOTE: INDEXED BY SqlDbType ENUM! MUST UPDATE THIS ARRAY WHEN UPDATING SqlDbType!
// ONLY ACCESS THIS GLOBAL FROM GetDefaultForType!
private static SmiMetaData[] __defaultValues =
{
DefaultBigInt, // SqlDbType.BigInt
DefaultBinary, // SqlDbType.Binary
DefaultBit, // SqlDbType.Bit
DefaultChar_NoCollation, // SqlDbType.Char
DefaultDateTime, // SqlDbType.DateTime
DefaultDecimal, // SqlDbType.Decimal
DefaultFloat, // SqlDbType.Float
DefaultImage, // SqlDbType.Image
DefaultInt, // SqlDbType.Int
DefaultMoney, // SqlDbType.Money
DefaultNChar_NoCollation, // SqlDbType.NChar
DefaultNText_NoCollation, // SqlDbType.NText
DefaultNVarChar_NoCollation, // SqlDbType.NVarChar
DefaultReal, // SqlDbType.Real
DefaultUniqueIdentifier, // SqlDbType.UniqueIdentifier
DefaultSmallDateTime, // SqlDbType.SmallDateTime
DefaultSmallInt, // SqlDbType.SmallInt
DefaultSmallMoney, // SqlDbType.SmallMoney
DefaultText_NoCollation, // SqlDbType.Text
DefaultTimestamp, // SqlDbType.Timestamp
DefaultTinyInt, // SqlDbType.TinyInt
DefaultVarBinary, // SqlDbType.VarBinary
DefaultVarChar_NoCollation, // SqlDbType.VarChar
DefaultVariant, // SqlDbType.Variant
DefaultNVarChar_NoCollation, // Placeholder for value 24
DefaultXml, // SqlDbType.Xml
DefaultNVarChar_NoCollation, // Placeholder for value 26
DefaultNVarChar_NoCollation, // Placeholder for value 27
DefaultNVarChar_NoCollation, // Placeholder for value 28
DefaultUdt_NoType, // Generic Udt
DefaultStructured, // Generic structured type
DefaultDate, // SqlDbType.Date
DefaultTime, // SqlDbType.Time
DefaultDateTime2, // SqlDbType.DateTime2
DefaultDateTimeOffset, // SqlDbType.DateTimeOffset
};
// static array of type names ordered by corresponding SqlDbType.
// NOTE: INDEXED BY SqlDbType ENUM! MUST UPDATE THIS ARRAY WHEN UPDATING SqlDbType!
// ONLY ACCESS THIS GLOBAL FROM get_TypeName!
private static string[] __typeNameByDatabaseType =
{
"bigint", // SqlDbType.BigInt
"binary", // SqlDbType.Binary
"bit", // SqlDbType.Bit
"char", // SqlDbType.Char
"datetime", // SqlDbType.DateTime
"decimal", // SqlDbType.Decimal
"float", // SqlDbType.Float
"image", // SqlDbType.Image
"int", // SqlDbType.Int
"money", // SqlDbType.Money
"nchar", // SqlDbType.NChar
"ntext", // SqlDbType.NText
"nvarchar", // SqlDbType.NVarChar
"real", // SqlDbType.Real
"uniqueidentifier", // SqlDbType.UniqueIdentifier
"smalldatetime", // SqlDbType.SmallDateTime
"smallint", // SqlDbType.SmallInt
"smallmoney", // SqlDbType.SmallMoney
"text", // SqlDbType.Text
"timestamp", // SqlDbType.Timestamp
"tinyint", // SqlDbType.TinyInt
"varbinary", // SqlDbType.VarBinary
"varchar", // SqlDbType.VarChar
"sql_variant", // SqlDbType.Variant
null, // placeholder for 24
"xml", // SqlDbType.Xml
null, // placeholder for 26
null, // placeholder for 27
null, // placeholder for 28
String.Empty, // SqlDbType.Udt -- get type name from Type.FullName instead.
String.Empty, // Structured types have user-defined type names.
"date", // SqlDbType.Date
"time", // SqlDbType.Time
"datetime2", // SqlDbType.DateTime2
"datetimeoffset", // SqlDbType.DateTimeOffset
};
// Internal setter to be used by constructors only! Modifies state!
private void SetDefaultsForType( SqlDbType dbType )
{
SmiMetaData smdDflt = GetDefaultForType( dbType );
_databaseType = dbType;
_maxLength = smdDflt.MaxLength;
_precision = smdDflt.Precision;
_scale = smdDflt.Scale;
_localeId = smdDflt.LocaleId;
_compareOptions = smdDflt.CompareOptions;
_clrType = null;
_isMultiValued = smdDflt._isMultiValued;
_fieldMetaData = smdDflt._fieldMetaData; // This is ok due to immutability
_extendedProperties = smdDflt._extendedProperties; // This is ok due to immutability
}
internal string TraceString() {
return TraceString(0);
}
virtual internal string TraceString(int indent) {
string indentStr = new String(' ', indent);
string fields = String.Empty;
if (null != _fieldMetaData) {
foreach(SmiMetaData fieldMd in _fieldMetaData) {
fields = String.Format(CultureInfo.InvariantCulture,
"{0}{1}\n\t", fields, fieldMd.TraceString(indent+5));
}
}
string properties = String.Empty;
if (null != _extendedProperties) {
foreach(SmiMetaDataProperty property in _extendedProperties.Values) {
properties = String.Format(CultureInfo.InvariantCulture,
"{0}{1} {2}\n\t", properties, indentStr, property.TraceString());
}
}
return String.Format(CultureInfo.InvariantCulture, "\n\t"
+"{0} SqlDbType={1:g}\n\t"
+"{0} MaxLength={2:d}\n\t"
+"{0} Precision={3:d}\n\t"
+"{0} Scale={4:d}\n\t"
+"{0} LocaleId={5:x}\n\t"
+"{0} CompareOptions={6:g}\n\t"
+"{0} Type={7}\n\t"
+"{0} MultiValued={8}\n\t"
+"{0} fields=\n\t{9}"
+"{0} properties=\n\t{10}",
indentStr,
SqlDbType,
MaxLength,
Precision,
Scale,
LocaleId,
CompareOptions,
(null!=Type) ? Type.ToString():"<null>",
IsMultiValued,
fields,
properties);
}
}
// SmiExtendedMetaData
//
// Adds server-specific type extension information to base metadata, but still portable across a specific server.
//
internal class SmiExtendedMetaData : SmiMetaData {
private string _name; // context-dependant identifier, ie. parameter name for parameters, column name for columns, etc.
// three-part name for typed xml schema and for udt names
private string _typeSpecificNamePart1;
private string _typeSpecificNamePart2;
private string _typeSpecificNamePart3;
[ObsoleteAttribute( "Not supported as of SMI v2. Will be removed when v1 support dropped. Use ctor without columns param." )]
internal SmiExtendedMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
SmiMetaData[] columns,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3) :
// Implement as calling the new ctor
this(
dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3 ) {
Debug.Assert( null == columns, "Row types not supported" );
}
internal SmiExtendedMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3) :
this(
dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
false,
null,
null,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3) {
}
// SMI V200 ctor.
internal SmiExtendedMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
bool isMultiValued,
IList<SmiExtendedMetaData> fieldMetaData,
SmiMetaDataPropertyCollection extendedProperties,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3) :
this( dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
null,
isMultiValued,
fieldMetaData,
extendedProperties,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3) {
}
// SMI V220 ctor.
internal SmiExtendedMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
string udtAssemblyQualifiedName,
bool isMultiValued,
IList<SmiExtendedMetaData> fieldMetaData,
SmiMetaDataPropertyCollection extendedProperties,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3 ):
base( dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
udtAssemblyQualifiedName,
isMultiValued,
fieldMetaData,
extendedProperties) {
Debug.Assert(null == name || MaxNameLength >= name.Length, "Name is too long");
_name = name;
_typeSpecificNamePart1 = typeSpecificNamePart1;
_typeSpecificNamePart2 = typeSpecificNamePart2;
_typeSpecificNamePart3 = typeSpecificNamePart3;
}
internal string Name {
get {
return _name;
}
}
internal string TypeSpecificNamePart1 {
get {
return _typeSpecificNamePart1;
}
}
internal string TypeSpecificNamePart2 {
get {
return _typeSpecificNamePart2;
}
}
internal string TypeSpecificNamePart3 {
get {
return _typeSpecificNamePart3;
}
}
internal override string TraceString(int indent) {
return String.Format(CultureInfo.InvariantCulture,
"{2} Name={0}"
+"{1}"
+"{2}TypeSpecificNamePart1='{3}'\n\t"
+"{2}TypeSpecificNamePart2='{4}'\n\t"
+"{2}TypeSpecificNamePart3='{5}'\n\t",
(null!=_name) ? _name : "<null>",
base.TraceString(indent),
new String(' ', indent),
(null!=TypeSpecificNamePart1) ? TypeSpecificNamePart1:"<null>",
(null!=TypeSpecificNamePart2) ? TypeSpecificNamePart2:"<null>",
(null!=TypeSpecificNamePart3) ? TypeSpecificNamePart3:"<null>");
}
}
// SmiParameterMetaData
//
// MetaData class to send parameter definitions to server.
// Sealed because we don't need to derive from it yet.
// IMPORTANT DEVNOTE: This class is being used for parameter encryption functionality, to get the type_info TDS object from SqlParameter.
// Please consider impact to that when changing this class. Refer to the callers of SqlParameter.GetMetadataForTypeInfo().
internal sealed class SmiParameterMetaData : SmiExtendedMetaData {
private ParameterDirection _direction;
[ObsoleteAttribute( "Not supported as of SMI v2. Will be removed when v1 support dropped. Use ctor without columns param." )]
internal SmiParameterMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
SmiMetaData[] columns,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3,
ParameterDirection direction) :
// Implement as calling the new ctor
this (
dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3,
direction ) {
Debug.Assert( null == columns, "Row types not supported" );
}
// SMI V100 (aka V3) ctor
internal SmiParameterMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3,
ParameterDirection direction) :
this(
dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
false,
null,
null,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3,
direction) {
}
// SMI V200 ctor.
internal SmiParameterMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
bool isMultiValued,
IList<SmiExtendedMetaData> fieldMetaData,
SmiMetaDataPropertyCollection extendedProperties,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3,
ParameterDirection direction) :
this( dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
null,
isMultiValued,
fieldMetaData,
extendedProperties,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3,
direction) {
}
// SMI V220 ctor.
internal SmiParameterMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
string udtAssemblyQualifiedName,
bool isMultiValued,
IList<SmiExtendedMetaData> fieldMetaData,
SmiMetaDataPropertyCollection extendedProperties,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3,
ParameterDirection direction) :
base( dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
udtAssemblyQualifiedName,
isMultiValued,
fieldMetaData,
extendedProperties,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3) {
Debug.Assert( ParameterDirection.Input == direction
|| ParameterDirection.Output == direction
|| ParameterDirection.InputOutput == direction
|| ParameterDirection.ReturnValue == direction, "Invalid direction: " + direction );
_direction = direction;
}
internal ParameterDirection Direction {
get {
return _direction;
}
}
internal override string TraceString(int indent) {
return String.Format(CultureInfo.InvariantCulture, "{0}"
+"{1} Direction={2:g}\n\t",
base.TraceString(indent),
new String(' ', indent),
Direction);
}
}
// SmiStorageMetaData
//
// This class represents the addition of storage-level attributes to the heirarchy (i.e. attributes from
// underlying table, source variables, or whatever).
//
// Most values use Null (either IsNullable == true or CLR null) to indicate "Not specified" state. Selection
// of which values allow "not specified" determined by backward compatibility.
//
// Maps approximately to TDS' COLMETADATA token with TABNAME and part of COLINFO thrown in.
internal class SmiStorageMetaData : SmiExtendedMetaData {
// AllowsDBNull is the only value required to be specified.
private bool _allowsDBNull; // could the column return nulls? equivalent to TDS's IsNullable bit
private string _serverName; // underlying column's server
private string _catalogName; // underlying column's database
private string _schemaName; // underlying column's schema
private string _tableName; // underlying column's table
private string _columnName; // underlying column's name
private SqlBoolean _isKey; // Is this one of a set of key columns that uniquely identify an underlying table?
private bool _isIdentity; // Is this from an identity column
private bool _isColumnSet; // Is this column the XML representation of a columnset?
[ObsoleteAttribute( "Not supported as of SMI v2. Will be removed when v1 support dropped. Use ctor without columns param." )]
internal SmiStorageMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
SmiMetaData[] columns,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3,
bool allowsDBNull,
string serverName,
string catalogName,
string schemaName,
string tableName,
string columnName,
SqlBoolean isKey,
bool isIdentity) :
// Implement as calling the new ctor
this (
dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3,
allowsDBNull,
serverName,
catalogName,
schemaName,
tableName,
columnName,
isKey,
isIdentity) {
Debug.Assert( null == columns, "Row types not supported" );
}
internal SmiStorageMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3,
bool allowsDBNull,
string serverName,
string catalogName,
string schemaName,
string tableName,
string columnName,
SqlBoolean isKey,
bool isIdentity) :
this(dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
false,
null,
null,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3,
allowsDBNull,
serverName,
catalogName,
schemaName,
tableName,
columnName,
isKey,
isIdentity) {
}
// SMI V200 ctor.
internal SmiStorageMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
bool isMultiValued,
IList<SmiExtendedMetaData> fieldMetaData,
SmiMetaDataPropertyCollection extendedProperties,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3,
bool allowsDBNull,
string serverName,
string catalogName,
string schemaName,
string tableName,
string columnName,
SqlBoolean isKey,
bool isIdentity) :
this( dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
null,
isMultiValued,
fieldMetaData,
extendedProperties,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3,
allowsDBNull,
serverName,
catalogName,
schemaName,
tableName,
columnName,
isKey,
isIdentity,
false) {
}
// SMI V220 ctor.
internal SmiStorageMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
string udtAssemblyQualifiedName,
bool isMultiValued,
IList<SmiExtendedMetaData> fieldMetaData,
SmiMetaDataPropertyCollection extendedProperties,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3,
bool allowsDBNull,
string serverName,
string catalogName,
string schemaName,
string tableName,
string columnName,
SqlBoolean isKey,
bool isIdentity,
bool isColumnSet) :
base( dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
udtAssemblyQualifiedName,
isMultiValued,
fieldMetaData,
extendedProperties,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3) {
_allowsDBNull = allowsDBNull;
_serverName = serverName;
_catalogName = catalogName;
_schemaName = schemaName;
_tableName = tableName;
_columnName = columnName;
_isKey = isKey;
_isIdentity = isIdentity;
_isColumnSet = isColumnSet;
}
internal bool AllowsDBNull {
get {
return _allowsDBNull;
}
}
internal string ServerName {
get {
return _serverName;
}
}
internal string CatalogName {
get {
return _catalogName;
}
}
internal string SchemaName {
get {
return _schemaName;
}
}
internal string TableName {
get {
return _tableName;
}
}
internal string ColumnName {
get {
return _columnName;
}
}
internal SqlBoolean IsKey {
get {
return _isKey;
}
}
internal bool IsIdentity {
get {
return _isIdentity;
}
}
internal bool IsColumnSet {
get {
return _isColumnSet;
}
}
internal override string TraceString(int indent) {
return String.Format(CultureInfo.InvariantCulture, "{0}"
+"{1} AllowsDBNull={2}\n\t"
+"{1} ServerName='{3}'\n\t"
+"{1} CatalogName='{4}'\n\t"
+"{1} SchemaName='{5}'\n\t"
+"{1} TableName='{6}'\n\t"
+"{1} ColumnName='{7}'\n\t"
+"{1} IsKey={8}\n\t"
+"{1} IsIdentity={9}\n\t",
base.TraceString(indent),
new String(' ', indent),
AllowsDBNull,
(null!=ServerName) ? ServerName:"<null>",
(null!=CatalogName) ? CatalogName:"<null>",
(null!=SchemaName) ? SchemaName:"<null>",
(null!=TableName) ? TableName:"<null>",
(null!=ColumnName) ? ColumnName:"<null>",
IsKey,
IsIdentity);
}
}
// SmiQueryMetaData
//
// Adds Query-specific attributes.
// Sealed since we don't need to extend it for now.
// Maps to full COLMETADATA + COLINFO + TABNAME tokens on TDS.
internal class SmiQueryMetaData : SmiStorageMetaData {
private bool _isReadOnly;
private SqlBoolean _isExpression;
private SqlBoolean _isAliased;
private SqlBoolean _isHidden;
[ObsoleteAttribute( "Not supported as of SMI v2. Will be removed when v1 support dropped. Use ctor without columns param." )]
internal SmiQueryMetaData(
SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
SmiMetaData[] columns,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3,
bool allowsDBNull,
string serverName,
string catalogName,
string schemaName,
string tableName,
string columnName,
SqlBoolean isKey,
bool isIdentity,
bool isReadOnly,
SqlBoolean isExpression,
SqlBoolean isAliased,
SqlBoolean isHidden ) :
// Implement as calling the new ctor
this (
dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3,
allowsDBNull,
serverName,
catalogName,
schemaName,
tableName,
columnName,
isKey,
isIdentity,
isReadOnly,
isExpression,
isAliased,
isHidden ) {
Debug.Assert( null == columns, "Row types not supported" );
}
internal SmiQueryMetaData( SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3,
bool allowsDBNull,
string serverName,
string catalogName,
string schemaName,
string tableName,
string columnName,
SqlBoolean isKey,
bool isIdentity,
bool isReadOnly,
SqlBoolean isExpression,
SqlBoolean isAliased,
SqlBoolean isHidden ) :
this( dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
false,
null,
null,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3,
allowsDBNull,
serverName,
catalogName,
schemaName,
tableName,
columnName,
isKey,
isIdentity,
isReadOnly,
isExpression,
isAliased,
isHidden) {
}
// SMI V200 ctor.
internal SmiQueryMetaData( SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
bool isMultiValued,
IList<SmiExtendedMetaData> fieldMetaData,
SmiMetaDataPropertyCollection extendedProperties,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3,
bool allowsDBNull,
string serverName,
string catalogName,
string schemaName,
string tableName,
string columnName,
SqlBoolean isKey,
bool isIdentity,
bool isReadOnly,
SqlBoolean isExpression,
SqlBoolean isAliased,
SqlBoolean isHidden) :
this( dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
null,
isMultiValued,
fieldMetaData,
extendedProperties,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3,
allowsDBNull,
serverName,
catalogName,
schemaName,
tableName,
columnName,
isKey,
isIdentity,
false,
isReadOnly,
isExpression,
isAliased,
isHidden ) {
}
// SMI V220 ctor.
internal SmiQueryMetaData( SqlDbType dbType,
long maxLength,
byte precision,
byte scale,
long localeId,
SqlCompareOptions compareOptions,
Type userDefinedType,
string udtAssemblyQualifiedName,
bool isMultiValued,
IList<SmiExtendedMetaData> fieldMetaData,
SmiMetaDataPropertyCollection extendedProperties,
string name,
string typeSpecificNamePart1,
string typeSpecificNamePart2,
string typeSpecificNamePart3,
bool allowsDBNull,
string serverName,
string catalogName,
string schemaName,
string tableName,
string columnName,
SqlBoolean isKey,
bool isIdentity,
bool isColumnSet,
bool isReadOnly,
SqlBoolean isExpression,
SqlBoolean isAliased,
SqlBoolean isHidden ) :
base( dbType,
maxLength,
precision,
scale,
localeId,
compareOptions,
userDefinedType,
udtAssemblyQualifiedName,
isMultiValued,
fieldMetaData,
extendedProperties,
name,
typeSpecificNamePart1,
typeSpecificNamePart2,
typeSpecificNamePart3,
allowsDBNull,
serverName,
catalogName,
schemaName,
tableName,
columnName,
isKey,
isIdentity,
isColumnSet ) {
_isReadOnly = isReadOnly;
_isExpression = isExpression;
_isAliased = isAliased;
_isHidden = isHidden;
}
internal bool IsReadOnly {
get {
return _isReadOnly;
}
}
internal SqlBoolean IsExpression {
get {
return _isExpression;
}
}
internal SqlBoolean IsAliased {
get {
return _isAliased;
}
}
internal SqlBoolean IsHidden {
get {
return _isHidden;
}
}
internal override string TraceString(int indent) {
return String.Format(CultureInfo.InvariantCulture, "{0}"
+"{1} IsReadOnly={2}\n\t"
+"{1} IsExpression={3}\n\t"
+"{1} IsAliased={4}\n\t"
+"{1} IsHidden={5}",
base.TraceString(indent),
new String(' ', indent),
AllowsDBNull,
IsExpression,
IsAliased,
IsHidden);
}
}
}
|