Skip to content

Commit 703950a

Browse files
committed
- refactoring - more methods marked as overridable
- enum types featured - begin transaction methods refactored - register connection bugfix - try/catch added into statements toXxxxx() methods - supporting assigning rows to Object
1 parent 765a40e commit 703950a

File tree

26 files changed

+1646
-1442
lines changed

26 files changed

+1646
-1442
lines changed
+30-30
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Imports System.ComponentModel
1+
Imports System.ComponentModel
22
Imports System.Dynamic
33
Imports System.Reflection
44

@@ -17,34 +17,34 @@ Namespace ActiveRecord
1717
Me.initResource()
1818
End Sub
1919

20-
''' <summary>
21-
''' Initializes 'Resource' class member (static or instance) with singleton Resource instance,
22-
''' if there is no instance yet. This method is always called by Entity constructor.
23-
''' </summary>
24-
Protected Sub initResource()
25-
Dim meType As Type = Me.GetType()
26-
Dim resourceMember As Reflection.MemberInfo = (
27-
From
28-
member As Reflection.MemberInfo In meType.GetMembers(
29-
BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic
30-
)
31-
Where
32-
member.Name = "Resource" AndAlso (
33-
TypeOf member Is Reflection.PropertyInfo OrElse
34-
TypeOf member Is Reflection.FieldInfo
35-
)
36-
Select
37-
member
38-
).FirstOrDefault()
39-
If resourceMember = Nothing Then Return
40-
If TypeOf resourceMember Is Reflection.PropertyInfo Then
41-
Dim pi As Reflection.PropertyInfo = DirectCast(resourceMember, Reflection.PropertyInfo)
42-
If pi.GetValue(Me, Nothing) = Nothing AndAlso pi.CanWrite Then pi.SetValue(Me, Resource.GetInstance(pi.PropertyType), Nothing)
43-
ElseIf TypeOf resourceMember Is Reflection.FieldInfo Then
44-
Dim fi As Reflection.FieldInfo = DirectCast(resourceMember, Reflection.FieldInfo)
45-
If fi.GetValue(Me) = Nothing Then fi.SetValue(Me, Resource.GetInstance(fi.FieldType))
46-
End If
47-
End Sub
20+
''' <summary>
21+
''' Initializes 'Resource' class member (static or instance) with singleton Resource instance,
22+
''' if there is no instance yet. This method is always called by Entity constructor.
23+
''' </summary>
24+
Protected Overridable Sub initResource()
25+
Dim meType As Type = Me.GetType()
26+
Dim resourceMember As Reflection.MemberInfo = (
27+
From
28+
member As Reflection.MemberInfo In meType.GetMembers(
29+
BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic
30+
)
31+
Where
32+
member.Name = "Resource" AndAlso (
33+
TypeOf member Is Reflection.PropertyInfo OrElse
34+
TypeOf member Is Reflection.FieldInfo
35+
)
36+
Select
37+
member
38+
).FirstOrDefault()
39+
If resourceMember = Nothing Then Return
40+
If TypeOf resourceMember Is Reflection.PropertyInfo Then
41+
Dim pi As Reflection.PropertyInfo = DirectCast(resourceMember, Reflection.PropertyInfo)
42+
If pi.GetValue(Me, Nothing) = Nothing AndAlso pi.CanWrite Then pi.SetValue(Me, Resource.GetInstance(pi.PropertyType), Nothing)
43+
ElseIf TypeOf resourceMember Is Reflection.FieldInfo Then
44+
Dim fi As Reflection.FieldInfo = DirectCast(resourceMember, Reflection.FieldInfo)
45+
If fi.GetValue(Me) = Nothing Then fi.SetValue(Me, Resource.GetInstance(fi.FieldType))
46+
End If
47+
End Sub
4848

49-
End Class
49+
End Class
5050
End Namespace
+121-85
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,127 @@
1-
Imports System.Data.Common
1+
Imports System.Data.Common
22
Imports Databasic.ActiveRecord
33

44
Namespace ActiveRecord
5-
Partial Public MustInherit Class Entity
5+
Partial Public MustInherit Class Entity
66

7-
''' <summary>
8-
''' Get column names from reader as list of strings.
9-
''' </summary>
10-
''' <param name="reader"></param>
11-
''' <returns></returns>
12-
Private Shared Function _getReaderRowColumns(reader As DbDataReader) As List(Of String)
13-
Return Enumerable.ToList(Of String)(
14-
Enumerable.Select(Of Integer, String)(
15-
Enumerable.Range(0, reader.FieldCount),
16-
New Func(Of Integer, String)(AddressOf reader.GetName)
17-
)
18-
)
19-
End Function
20-
''' <summary>
21-
''' Return True if type is descriptable type by custom attributes, not primitive, not an object.
22-
''' </summary>
23-
''' <param name="instanceType">Instance type to check out.</param>
24-
''' <returns>True if descriptable.</returns>
25-
Private Shared Function _isDescriptableType(ByRef instanceType As Type) As Boolean
26-
Return Not instanceType.IsPrimitive AndAlso instanceType.FullName <> "System.String" AndAlso instanceType.FullName <> "System.Object"
27-
End Function
28-
''' <summary>
29-
''' Set up current reader row columns into instance properties and fields.
30-
''' </summary>
31-
''' <param name="reader">DbDataReader with current row moved, where current row will be used to fill instance properties and fields.</param>
32-
''' <param name="readerColumnNames">Columns in reader in proper order.</param>
33-
''' <param name="instance">Instance to fill.</param>
34-
Private Shared Sub _readerRowToInstance(ByRef reader As DbDataReader, ByRef readerColumnNames As List(Of String), ByRef columnsByDbNames As Dictionary(Of String, Databasic.MemberInfo), ByRef instance As Object, isEntity As Boolean)
35-
Dim mi As Databasic.MemberInfo
36-
Dim rawValueTypeCode As TypeCode
37-
Dim assigned As Boolean
38-
Dim propInfo As Reflection.PropertyInfo
39-
Dim targetName As String
40-
Dim formatProvider As IFormatProvider
41-
Dim rawValue As Object
42-
Dim targetValue As Object
43-
Dim entity As Databasic.ActiveRecord.Entity
44-
For Each readerColumnName As String In readerColumnNames
45-
assigned = False
46-
rawValue = reader(readerColumnName)
47-
targetName = readerColumnName
48-
targetValue = Nothing
49-
If columnsByDbNames.ContainsKey(readerColumnName) Then
50-
mi = columnsByDbNames(readerColumnName)
51-
rawValueTypeCode = Type.GetTypeCode(rawValue.GetType())
52-
If (rawValueTypeCode = Constants.StringTypeCode AndAlso mi.TrimChars.Length > 0) Then
53-
rawValue = rawValue.ToString().Trim(mi.TrimChars)
54-
ElseIf rawValueTypeCode = Type.GetTypeCode(mi.Type) Then
55-
targetValue = rawValue
56-
ElseIf mi.Type.IsEnum Then
57-
targetValue = System.[Enum].Parse(mi.Type, rawValue.ToString())
58-
Else
59-
formatProvider = If(mi.FormatProvider, System.Globalization.CultureInfo.CurrentCulture)
60-
targetValue = If(TypeOf rawValue Is DBNull, Nothing, Convert.ChangeType(rawValue, mi.Type, formatProvider))
61-
End If
62-
If (mi.MemberInfoType = MemberInfoType.Prop) Then
63-
propInfo = DirectCast(mi.MemberInfo, Reflection.PropertyInfo)
64-
If propInfo.CanWrite Then
65-
propInfo.SetValue(instance, targetValue, Nothing)
66-
assigned = True
67-
Else
68-
targetName = mi.Name
69-
End If
70-
Else
71-
DirectCast(mi.MemberInfo, Reflection.FieldInfo).SetValue(instance, targetValue)
72-
assigned = True
73-
End If
74-
End If
75-
If isEntity Then
76-
targetValue = If(targetValue, rawValue)
77-
entity = DirectCast(instance, Databasic.ActiveRecord.Entity)
78-
If Not assigned Then
79-
entity._reserveStore.Item(targetName) = targetValue
80-
End If
81-
If entity._initialData.ContainsKey(targetName) Then
82-
entity._initialData(targetName) = targetValue
83-
Else
84-
entity._initialData.Add(targetName, targetValue)
85-
End If
86-
End If
87-
Next
88-
End Sub
7+
''' <summary>
8+
''' Get column names from reader as list of strings.
9+
''' </summary>
10+
''' <param name="reader"></param>
11+
''' <returns></returns>
12+
Private Shared Function _getReaderRowColumns(reader As DbDataReader) As List(Of String)
13+
Return Enumerable.ToList(Of String)(
14+
Enumerable.Select(Of Integer, String)(
15+
Enumerable.Range(0, reader.FieldCount),
16+
New Func(Of Integer, String)(AddressOf reader.GetName)
17+
)
18+
)
19+
End Function
20+
''' <summary>
21+
''' Set up current reader row columns into instance properties and fields.
22+
''' </summary>
23+
''' <param name="reader">DbDataReader with current row moved, where current row will be used to fill instance properties and fields.</param>
24+
''' <param name="readerColumnNames">Columns in reader in proper order.</param>
25+
''' <param name="instance">Instance to fill.</param>
26+
Private Shared Sub _readerRowToTypedInstance(
27+
ByRef reader As DbDataReader,
28+
ByRef readerColumnNames As List(Of String),
29+
ByRef columnsByDbNames As Dictionary(Of String, Databasic.MemberInfo),
30+
ByRef instance As Object,
31+
isEntity As Boolean
32+
)
33+
Dim mi As Databasic.MemberInfo
34+
Dim rawValueTypeCode As TypeCode
35+
Dim assigned As Boolean
36+
Dim propInfo As Reflection.PropertyInfo
37+
Dim targetName As String
38+
Dim formatProvider As IFormatProvider
39+
Dim rawValue As Object
40+
Dim targetValue As Object
41+
For Each readerColumnName As String In readerColumnNames
42+
assigned = False
43+
rawValue = reader(readerColumnName)
44+
targetName = readerColumnName
45+
targetValue = Nothing
46+
If columnsByDbNames.ContainsKey(readerColumnName) Then
47+
mi = columnsByDbNames(readerColumnName)
48+
rawValueTypeCode = Type.GetTypeCode(rawValue.GetType())
49+
If (rawValueTypeCode = Constants.StringTypeCode AndAlso mi.TrimChars.Length > 0) Then
50+
rawValue = rawValue.ToString().Trim(mi.TrimChars)
51+
ElseIf rawValueTypeCode = Type.GetTypeCode(mi.Type) Then
52+
targetValue = rawValue
53+
ElseIf mi.Type.IsEnum Then
54+
targetValue = Entity._parseEnumMemberValue(mi, rawValue)
55+
Else
56+
formatProvider = If(mi.FormatProvider, System.Globalization.CultureInfo.CurrentCulture)
57+
targetValue = If(TypeOf rawValue Is DBNull, Nothing, Convert.ChangeType(rawValue, mi.Type, formatProvider))
58+
End If
59+
If (mi.MemberInfoType = MemberInfoType.Prop) Then
60+
propInfo = DirectCast(mi.MemberInfo, Reflection.PropertyInfo)
61+
If propInfo.CanWrite Then
62+
propInfo.SetValue(instance, targetValue, Nothing)
63+
assigned = True
64+
End If
65+
Else
66+
DirectCast(mi.MemberInfo, Reflection.FieldInfo).SetValue(instance, targetValue)
67+
assigned = True
68+
End If
69+
targetName = mi.Name
70+
End If
71+
If isEntity Then
72+
Entity._setUpentityValueToReserveStoreAndInitialValues(
73+
DirectCast(instance, Databasic.ActiveRecord.Entity),
74+
targetName, rawValue, targetValue, assigned
75+
)
76+
End If
77+
Next
78+
End Sub
8979

90-
End Class
80+
Private Shared Sub _readerRowToAnonymousInstance(
81+
ByRef reader As DbDataReader,
82+
ByRef readerColumnNames As List(Of String),
83+
ByRef instance As Databasic.Object
84+
)
85+
For Each readerColumnName As String In readerColumnNames
86+
Entity._setUpentityValueToReserveStoreAndInitialValues(
87+
instance, readerColumnName, Nothing, reader(readerColumnName), False
88+
)
89+
Next
90+
End Sub
91+
92+
Private Shared Function _parseEnumMemberValue(mi As MemberInfo, rawValue As Object) As Object
93+
If mi.UseEnumUnderlyingValue Then
94+
Dim underType As Type = System.Enum.GetUnderlyingType(mi.Type),
95+
underValue = Convert.ChangeType(rawValue, underType),
96+
values = System.[Enum].GetValues(mi.Type)
97+
For i = 0 To values.Length - 1
98+
If (underValue = values(i)) Then
99+
Return values(i)
100+
End If
101+
Next
102+
Return Nothing
103+
Else
104+
Return System.[Enum].Parse(mi.Type, rawValue.ToString())
105+
End If
106+
End Function
107+
108+
Private Shared Sub _setUpentityValueToReserveStoreAndInitialValues(
109+
entity As Databasic.ActiveRecord.Entity,
110+
targetName As String,
111+
rawValue As Object,
112+
targetValue As Object,
113+
assigned As Boolean
114+
)
115+
targetValue = If(targetValue, rawValue)
116+
If Not assigned Then
117+
entity._reserveStore.Item(targetName) = targetValue
118+
End If
119+
If entity._initialData.ContainsKey(targetName) Then
120+
entity._initialData(targetName) = targetValue
121+
Else
122+
entity._initialData.Add(targetName, targetValue)
123+
End If
124+
End Sub
125+
126+
End Class
91127
End Namespace

0 commit comments

Comments
 (0)