Welcome to mirror list, hosted at ThFree Co, Russian Federation.

Perspective.cs « Metadata « Data « System « System.Data.Entity « referencesource « class « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b3834ecef3576900f129101c926e7fa217e3e202 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
//---------------------------------------------------------------------
// <copyright file="Perspective.cs" company="Microsoft">
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//
// @owner       [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System.Diagnostics;
using System.Linq;

namespace System.Data.Metadata.Edm
{
    using System.Collections.Generic;

    /// <summary>
    /// Internal helper class for query
    /// </summary>
    internal abstract class Perspective
    {
        #region Constructors
        /// <summary>
        /// Creates a new instance of perspective class so that query can work
        /// ignorant of all spaces
        /// </summary>
        /// <param name="metadataWorkspace">runtime metadata container</param>
        /// <param name="targetDataspace">target dataspace for the perspective</param>
        internal Perspective(MetadataWorkspace metadataWorkspace,
                             DataSpace targetDataspace)
        {
            EntityUtil.CheckArgumentNull(metadataWorkspace, "metadataWorkspace");

            m_metadataWorkspace = metadataWorkspace;
            m_targetDataspace = targetDataspace;
        }
        #endregion

        #region Fields
        private MetadataWorkspace m_metadataWorkspace;
        private DataSpace m_targetDataspace;
        #endregion

        #region Methods

        /// <summary>
        /// Given the type in the target space and the member name in the source space,
        /// get the corresponding member in the target space
        /// For e.g.  consider a Conceptual Type 'Foo' with a member 'Bar' and a CLR type
        /// 'XFoo' with a member 'YBar'. If one has a reference to Foo one can
        /// invoke GetMember(Foo,"YBar") to retrieve the member metadata for bar
        /// </summary>
        /// <param name="type">The type in the target perspective</param>
        /// <param name="memberName">the name of the member in the source perspective</param>
        /// <param name="ignoreCase">Whether to do case-sensitive member look up or not</param>
        /// <param name="outMember">returns the member in target space, if a match is found</param>
        internal virtual bool TryGetMember(StructuralType type, String memberName, bool ignoreCase, out EdmMember outMember)
        {
            EntityUtil.CheckArgumentNull(type, "type");
            EntityUtil.CheckStringArgument(memberName, "memberName");
            outMember = null;
            return type.Members.TryGetValue(memberName, ignoreCase, out outMember);
        }
        internal bool TryGetEnumMember(EnumType type, String memberName, bool ignoreCase, out EnumMember outMember)
        {
            EntityUtil.CheckArgumentNull(type, "type");
            EntityUtil.CheckStringArgument(memberName, "memberName");
            outMember = null;
            return type.Members.TryGetValue(memberName, ignoreCase, out outMember);
        }

        /// <summary>
        /// Returns the extent in the target space, for the given entity container.
        /// </summary>
        /// <param name="entityContainer">name of the entity container in target space</param>
        /// <param name="extentName">name of the extent</param>
        /// <param name="ignoreCase">Whether to do case-sensitive member look up or not</param>
        /// <param name="outSet">extent in target space, if a match is found</param>
        /// <returns>returns true, if a match is found otherwise returns false</returns>
        internal bool TryGetExtent(EntityContainer entityContainer, String extentName, bool ignoreCase, out EntitySetBase outSet)
        {
            // There are no entity containers in the OSpace. So there is no mapping involved.
            // Hence the name should be a valid name in the CSpace.
            return entityContainer.BaseEntitySets.TryGetValue(extentName, ignoreCase, out outSet);
        }

        /// <summary>
        /// Returns the function import in the target space, for the given entity container.
        /// </summary>
        internal bool TryGetFunctionImport(EntityContainer entityContainer, String functionImportName, bool ignoreCase, out EdmFunction functionImport)
        {
            // There are no entity containers in the OSpace. So there is no mapping involved.
            // Hence the name should be a valid name in the CSpace.
            functionImport = null;
            if (ignoreCase)
            {
                functionImport = entityContainer.FunctionImports.Where(fi => String.Equals(fi.Name, functionImportName, StringComparison.OrdinalIgnoreCase)).SingleOrDefault();
            }
            else
            {
                functionImport = entityContainer.FunctionImports.Where(fi => fi.Name == functionImportName).SingleOrDefault();
            }
            return functionImport != null;
        }

        /// <summary>
        /// Get the default entity container
        /// returns null for any perspective other 
        /// than the CLR perspective
        /// </summary>
        /// <returns>The default container</returns>
        internal virtual EntityContainer GetDefaultContainer()
        {
            return null;
        }

        /// <summary>
        /// Get an entity container based upon the strong name of the container
        /// If no entity container is found, returns null, else returns the first one/// </summary>
        /// <param name="name">name of the entity container</param>
        /// <param name="ignoreCase">true for case-insensitive lookup</param>
        /// <param name="entityContainer">returns the entity container if a match is found</param>
        /// <returns>returns true if a match is found, otherwise false</returns>
        internal virtual bool TryGetEntityContainer(string name, bool ignoreCase, out EntityContainer entityContainer)
        {
            return MetadataWorkspace.TryGetEntityContainer(name, ignoreCase, TargetDataspace, out entityContainer);
        }

        /// <summary>
        /// Gets a type with the given name in the target space.
        /// </summary>
        /// <param name="fullName">full name of the type</param>
        /// <param name="ignoreCase">true for case-insensitive lookup</param>
        /// <param name="typeUsage">TypeUsage for the type</param>
        /// <returns>returns true if a match was found, otherwise false</returns>
        internal abstract bool TryGetTypeByName(string fullName, bool ignoreCase, out TypeUsage typeUsage);

        /// <summary>
        /// Returns overloads of a function with the given name in the target space.
        /// </summary>
        /// <param name="namespaceName">namespace of the function</param>
        /// <param name="functionName">name of the function</param>
        /// <param name="ignoreCase">true for case-insensitive lookup</param>
        /// <param name="functionOverloads">function overloads</param>
        /// <returns>returns true if a match was found, otherwise false</returns>
        internal bool TryGetFunctionByName(string namespaceName, string functionName, bool ignoreCase, out IList<EdmFunction> functionOverloads)
        {
            EntityUtil.CheckStringArgument(namespaceName, "namespaceName");
            EntityUtil.CheckStringArgument(functionName, "functionName");

            var fullName = namespaceName + "." + functionName;

            // First look for a model-defined function in the target space.
            ItemCollection itemCollection = m_metadataWorkspace.GetItemCollection(m_targetDataspace);
            IList<EdmFunction> overloads =
                m_targetDataspace == DataSpace.SSpace ?
                ((StoreItemCollection)itemCollection).GetCTypeFunctions(fullName, ignoreCase) :
                itemCollection.GetFunctions(fullName, ignoreCase);

            if (m_targetDataspace == DataSpace.CSpace)
            {
                // Then look for a function import.
                if (overloads == null || overloads.Count == 0)
                {
                    EntityContainer entityContainer;
                    if (this.TryGetEntityContainer(namespaceName, /*ignoreCase:*/ false, out entityContainer))
                    {
                        EdmFunction functionImport;
                        if (this.TryGetFunctionImport(entityContainer, functionName, /*ignoreCase:*/ false, out functionImport))
                        {
                            overloads = new EdmFunction[] { functionImport };
                        }
                    }
                }

                // Last, look in SSpace.
                if (overloads == null || overloads.Count == 0)
                {
                    ItemCollection storeItemCollection;
                    if (m_metadataWorkspace.TryGetItemCollection(DataSpace.SSpace, out storeItemCollection))
                    {
                        overloads = ((StoreItemCollection)storeItemCollection).GetCTypeFunctions(fullName, ignoreCase);
                    }
                }
            }

            functionOverloads = (overloads != null && overloads.Count > 0) ? overloads : null;
            return functionOverloads != null;
        }

        /// <summary>
        /// Return the metadata workspace
        /// </summary>
        internal MetadataWorkspace MetadataWorkspace
        {
            get
            {
                return m_metadataWorkspace;
            }
        }

        /// <summary>
        /// returns the primitive type for a given primitive type kind.
        /// </summary>
        /// <param name="primitiveTypeKind"></param>
        /// <param name="primitiveType"></param>
        /// <returns></returns>
        internal virtual bool TryGetMappedPrimitiveType(PrimitiveTypeKind primitiveTypeKind, out PrimitiveType primitiveType)
        {
            primitiveType = m_metadataWorkspace.GetMappedPrimitiveType(primitiveTypeKind, DataSpace.CSpace);

            return (null != primitiveType);
        }

        //
        // This property will be needed to construct keys for transient types
        //
        /// <summary>
        /// Returns the target dataspace for this perspective
        /// </summary>
        internal DataSpace TargetDataspace
        {
            get
            {
                return m_targetDataspace;
            }
        }
        #endregion
    }
}