1 #Region "Microsoft.VisualBasic::49bb9d749754395e059aadbfee5ce91e, Microsoft.VisualBasic.Core\ComponentModel\DataSource\SchemaMaps\Mappings.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Module Mappings
35     
36     '         Function: FieldNameMappings, GetColumnName, (+2 OverloadsGetFields, GetSchema, GetSchemaName
37     
38     
39     ' /********************************************************************************/
40
41 #End Region
42
43 Imports System.Data.Linq.Mapping
44 Imports System.Reflection
45 Imports System.Runtime.CompilerServices
46 Imports Microsoft.VisualBasic.Language
47
48 Namespace ComponentModel.DataSourceModel.SchemaMaps
49
50     Public Module Mappings
51
52         <Extension>
53         Public Function GetSchemaName(Of T As Attribute)(
54                                      type As Type,
55                                      getName As Func(Of T, String),
56                                      Optional explict As Boolean = FalseAs String
57
58             Dim attrs As Object() = type.GetCustomAttributes(GetType(T), inherit:=True)
59
60             If attrs.IsNullOrEmpty Then
61                 If explict Then
62                     Return type.Name
63                 Else
64                     Return Nothing
65                 End If
66             Else
67                 Dim attr As T = DirectCast(attrs(Scan0), T)
68                 Dim name As String = getName(attr)
69                 Return name
70             End If
71         End Function
72
73         ''' <summary>
74         ''' 这个只是得到最上面的一层属性值
75         ''' </summary>
76         ''' <typeparam name="T"></typeparam>
77         ''' <param name="type"></param>
78         ''' <param name="getName"></param>
79         ''' <param name="explict">
80         ''' 当自定义属性不存在的时候,隐式的使用域名或者属性名作为名称,否则会跳过该对象,默认是跳过该对象
81         ''' </param>
82         ''' <returns></returns>
83         <Extension>
84         Public Function GetFields(Of T As {Attribute})(type As Type, getName As Func(Of T, String), Optional explict As Boolean = FalseAs BindProperty(Of T)()
85             Dim out As New List(Of BindProperty(Of T))
86
87             For Each field As FieldInfo In type.GetFields
88                 Dim attr As T = field.GetCustomAttribute(Of T)
89
90                 If attr Is Nothing Then
91                     If explict Then
92                         out += New BindProperty(Of T)(field)
93                     End If
94                 Else
95                     out += New BindProperty(Of T)(attr, field) With {
96                         .Identity = getName(attr)
97                     }
98                 End If
99             Next
100
101             For Each [property] As PropertyInfo In type.GetProperties
102                 Dim attr As T = [property].GetCustomAttribute(Of T)
103
104                 If attr Is Nothing Then
105                     If explict Then
106                         out += New BindProperty(Of T)([property])
107                     End If
108                 Else
109                     out += New BindProperty(Of T)(attr, [property]) With {
110                         .Identity = getName(attr)
111                     }
112                 End If
113             Next
114
115             Return out
116         End Function
117
118         <MethodImpl(MethodImplOptions.AggressiveInlining)>
119         Public Function GetFields(Of T)(Optional explict As Boolean = TrueAs BindProperty(Of ColumnAttribute)()
120             Return GetType(T).GetFields(Of ColumnAttribute)(Function(o) o.Name, explict:=explict)
121         End Function
122
123         ''' <summary>
124         ''' 获取从目标类型定义之中的从类型成员域名称映射到列名称的哈希表
125         ''' </summary>
126         ''' <typeparam name="T"></typeparam>
127         ''' <param name="explict"></param>
128         ''' <param name="reversed">
129         ''' 当这个参数为真的时候,将会:
130         ''' 
131         ''' ```
132         ''' <see cref="ColumnAttribute.Name"/> => <see cref="MemberInfo.Name"/>
133         ''' ```
134         ''' </param>
135         ''' <returns></returns>
136         Public Function FieldNameMappings(Of T)(Optional explict As Boolean = FalseOptional reversed As Boolean = FalseAs Dictionary(Of StringString)
137             Dim fields As BindProperty(Of ColumnAttribute)() = GetFields(Of T)(explict)
138             Dim table As Dictionary(Of StringString)
139
140             If Not reversed Then
141                 table = fields.ToDictionary(Function(field)
142                                                 ' 获取类型定义之中的成员的属性的反射名称
143                                                 Return field.member.Name
144                                             End Function,
145                                             Function(map)
146                                                 ' 获取该成员上面的自定义属性之中所记录的名称
147                                                 Return map.GetColumnName
148                                             End Function)
149             Else
150                 table = fields _
151                     .ToDictionary(Function(map)
152                                       ' 获取该成员上面的自定义属性之中所记录的名称
153                                       Return map.GetColumnName
154                                   End Function,
155                                   Function(field)
156                                       ' 获取类型定义之中的成员的属性的反射名称
157                                       Return field.member.Name
158                                   End Function)
159             End If
160
161             Return table
162         End Function
163
164         <Extension>
165         Public Function GetColumnName([property] As BindProperty(Of ColumnAttribute)) As String
166             If [property].field Is Nothing OrElse [property].field.Name.StringEmpty Then
167                 Return [property].Identity
168             Else
169                 Return [property].field.Name
170             End If
171         End Function
172
173         <Extension>
174         Public Function GetSchema(Of TField As Attribute, TTable As Attribute)(
175                                      type As Type,
176                                      getTableName As Func(Of TTable, String),
177                                      getField As Func(Of TField, String),
178                                      Optional explict As Boolean = FalseAs Schema(Of TField)
179
180             Return New Schema(Of TField) With {
181                 .SchemaName = type.GetSchemaName(Of TTable)(getTableName, explict),
182                 .Fields = type.GetFields(Of TField)(getField, explict)
183             }
184         End Function
185     End Module
186 End Namespace