| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- //------------------------------------------------------------------------------
- // <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.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
- }
- }
|