From: Richard B. <rb...@us...> - 2005-03-11 04:41:06
|
Update of /cvsroot/jcframework/dotnet In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21135 Modified Files: CClassMap.vb CInjectedObject.vb CInjectedObjects.vb CPersistenceBroker.vb CRelationalDatabase.vb Log Message: Bug fixes for interface based persistence. Problems with 3+ levels in the hierarchy. Also some small changes to finalize. Index: CRelationalDatabase.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CRelationalDatabase.vb,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- CRelationalDatabase.vb 28 Oct 2004 00:16:12 -0000 1.21 +++ CRelationalDatabase.vb 11 Mar 2005 04:40:56 -0000 1.22 @@ -1265,6 +1265,7 @@ Protected Overrides Sub Finalize() ' Simply call Dispose(False). Dispose(False) + MyBase.finalize() End Sub Public Overridable Function supportsSelectOffsets() As Boolean Implements _CRelationalDatabase.supportsSelectOffsets Index: CPersistenceBroker.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CPersistenceBroker.vb,v retrieving revision 1.98 retrieving revision 1.99 diff -u -d -r1.98 -r1.99 --- CPersistenceBroker.vb 3 Mar 2005 00:38:23 -0000 1.98 +++ CPersistenceBroker.vb 11 Mar 2005 04:40:55 -0000 1.99 @@ -295,6 +295,8 @@ Dim isfirst As Boolean = True Dim am As CAttributeMap Dim fromClass, toClass As CClassMap + Dim paramCount As Integer + Dim skipClass As Boolean cm = obj.GetClassMap @@ -336,17 +338,24 @@ Dim statement As New CSqlStatement cm2 = cm + paramCount = 0 + skipClass = False Do If useFind Then + If Not skipClass Then For i = 1 To cm2.getFindSize am = cm2.FindAttributeMaps(i) - statement.addSqlParameter(i, obj.GetValueByAttribute(am.Name), am.ColumnMap) + paramCount += 1 + statement.addSqlParameter(paramCount, obj.GetValueByAttribute(am.Name), am.ColumnMap) Next i + End If + skipClass = Not cm2.SharedTableField Is Nothing cm2 = cm2.SuperClass Else For i = 1 To cm2.getKeySize am = cm2.getKeyAttributeMap(i) - statement.addSqlParameter(i, obj.GetValueByAttribute(am.Name), am.ColumnMap) + paramCount += 1 + statement.addSqlParameter(paramCount, obj.GetValueByAttribute(am.Name), am.ColumnMap) Next i cm2 = Nothing End If @@ -421,6 +430,7 @@ 'Only process one-to-one relationships on the first record retrieved If udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_ONE And i = 0 Then gotValue = False + classMapCount += Me.getChildCountForMultipleInheritance(udamap.ToClass) - 1 targetobj = obj.GetObjectByAttribute(udamap.FromClassTarget) If Not targetobj Is Nothing Then 'if the class as child classes then check if the targetobj is of type child @@ -467,8 +477,8 @@ If udamap.ToClass.ChildrenMaps.Count > 0 Then targetobj = Me.createTargetObjectForMultipleInheritance(udamap.ToClass, obj.GetObjectType, obj.GetObjectType.Namespace, rs.ResultSet.Tables(0).Rows(i), joins, conn) 'update classMapCount with the child count number - classMapCount += Me.getChildCountForMultipleInheritance(udamap.ToClass) - classMapCount -= 1 'This is because we added one in the beginning of the for loop + 'classMapCount += Me.getChildCountForMultipleInheritance(udamap.ToClass) + 'classMapCount -= 1 'This is because we added one in the beginning of the for loop If Not targetobj Is Nothing AndAlso targetobj.Persistent Then tmpObj = m_cache.Item(targetobj) @@ -1310,10 +1320,12 @@ 'the object inherits a child class, otherwise we can get the wrong class map 'returned. If Not tmpCMap Is Nothing Then - If ClassMap Is Nothing Then ClassMap = tmpCMap - If tmpCMap.ChildrenMaps.Count = 0 Then + If ClassMap Is Nothing Then ClassMap = tmpCMap - Exit For + Else + If tmpCMap.IsChildOf(ClassMap) Then + ClassMap = tmpCMap + End If End If End If Next @@ -2582,8 +2594,9 @@ Return queue End If If includeBaseObject Then - queue.Enqueue(obj) + AddToQueue(obj, queue) End If + Return queue Else 'Determine if the object needs saving 'But, countinue to determine if the object's associations need saving @@ -2593,11 +2606,10 @@ 'If obj.GetObjectType.IsSubclassOf(GetType(CPersistentObject)) Then If CType(obj.GetSourceObject, IValidation).IsValid Then 'Do not save if object is not valid 'obj.IsDirty = False 'Added to queue so clear dirty flag - queue.Enqueue(obj) + AddToQueue(obj, queue) End If Else - 'obj.IsDirty = False - queue.Enqueue(obj) + AddToQueue(obj, queue) End If End If End If @@ -2605,6 +2617,7 @@ 'Now process the object associations to see what else needs saving cm = obj.GetClassMap() + While Not cm Is Nothing For i = 1 To cm.getStraightAssociationMapSize udamap = cm.getStraightAssociationMap(i) If udamap.SaveAutomatic Then @@ -2621,7 +2634,7 @@ For k = 0 To col.Count() - 1 tmpObj = col.Item(k) If Not tmpObj.GetType.IsSubclassOf(GetType(CPersistentObject)) Then - value = LocateOrCacheInjObject(tmpObj) + value = getInjectedObject(tmpObj) Else value = tmpObj End If @@ -2646,7 +2659,7 @@ For k = 0 To col.Count() - 1 tmpObj = col.Item(k) If Not tmpObj.GetType.IsSubclassOf(GetType(CPersistentObject)) Then - value = LocateOrCacheInjObject(tmpObj) + value = getInjectedObject(tmpObj) Else value = tmpObj End If @@ -2670,39 +2683,9 @@ End If End If Next i + cm = cm.SuperClass + End While - 'now process the parent objects. Note that children will not be re-added as - 'they are already marked as non-dirty at the start of the method. - 'Also, if the child and parent share the same database table the parent object - 'is not added to the stack as it will be saved in savePrivateObject() - If cm.SharedTableField Is Nothing Then - If Not cm.SuperClass Is Nothing Then - tmpObj = obj.GetObjectByClassMap(cm.SuperClass) - If Not tmpObj.GetType.IsSubclassOf(GetType(CPersistentObject)) Then - value = LocateOrCacheInjObject(tmpObj) - Else - value = tmpObj - End If - queue.Enqueue(value) - value.IsDirty = False 'Added to queue so clear dirty flag - For Each o In getObjectsToSave(value, False, checkAssociationsRecursivly) - queue.Enqueue(o) - Next - End If - Else - If Not cm.SuperClass Is Nothing Then - tmpObj = obj.GetObjectByClassMap(cm.SuperClass) - If Not tmpObj.GetType.IsSubclassOf(GetType(CPersistentObject)) Then - value = LocateOrCacheInjObject(tmpObj) - Else - value = tmpObj - End If - value.IsDirty = False 'make sure that the parent object is not added - For Each o In getObjectsToSave(value, False, checkAssociationsRecursivly) - queue.Enqueue(o) - Next - End If - End If Return queue End Function @@ -2820,6 +2803,7 @@ Protected Overrides Sub Finalize() ' Simply call Dispose(False). Dispose(False) + MyBase.Finalize() End Sub Friend ReadOnly Property Disposed() As Boolean @@ -3217,4 +3201,27 @@ End If Next End Sub + + Private Sub AddToQueue(ByVal obj As Object, ByRef queue As Queue) + Call AddToQueue(obj, queue, True) + End Sub + Private Sub AddToQueue(ByVal obj As Object, ByRef queue As Queue, ByVal includeObject As Boolean) + 'Called recursively so that objects with superclasses are queued from the + 'top most object down. + Dim cm As CClassMap + Dim tmpobj As Object + cm = obj.GetClassMap() + If Not cm.SuperClass Is Nothing Then + tmpobj = obj.GetObjectByClassMap(cm.SuperClass) + If cm.SharedTableField Is Nothing Then + AddToQueue(tmpobj, queue, True) + Else + AddToQueue(tmpobj, queue, False) + End If + End If + If includeObject Then + queue.Enqueue(obj) + End If + Return + End Sub End Class \ No newline at end of file Index: CInjectedObject.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CInjectedObject.vb,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- CInjectedObject.vb 3 Mar 2005 00:38:23 -0000 1.15 +++ CInjectedObject.vb 11 Mar 2005 04:40:55 -0000 1.16 @@ -76,7 +76,8 @@ End If Dim f, fields() As FieldInfo Dim value As Object - Dim t, iListType, iDicType As Type Try + Dim t, iListType, iDicType As Type + Try t = sourceObject.GetType While Not t Is Nothing fields = t.GetFields(BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.Public) @@ -96,7 +97,8 @@ t = Nothing End If End While - CPersistenceBroker.CopyCollections(sourceObject, targetObject) Catch ex As Exception + CPersistenceBroker.CopyCollections(sourceObject, targetObject) + Catch ex As Exception Debug.WriteLine(ex.Message) End Try End Sub @@ -104,61 +106,65 @@ Public Function getClassMap() As CClassMap Implements IPersistableObject.getClassMap Dim tmpCMap As CClassMap If m_classmap Is Nothing Then - m_classmap = getClassMap(TypeName(m_object), m_object.GetType.FullName) - If m_classmap Is Nothing Then - 'try to find an interface that is mapped - first mapped interface we find will be used - Dim intType, tmpType, interfaces() As Type - interfaces = m_object.GetType.GetInterfaces + 'm_classmap = getClassMap(TypeName(m_object), m_object.GetType.FullName) + 'If m_classmap Is Nothing Then + Dim persistenceBroker As CPersistenceBroker + persistenceBroker = getPersistenceBrokerInstance() + m_classmap = persistenceBroker.getClassMap(m_object.GetType) - '----------------------------------------- - Dim n, m As Integer - Dim super As CClassMap + ''try to find an interface that is mapped - first mapped interface we find will be used + 'Dim intType, tmpType, interfaces() As Type + 'interfaces = m_object.GetType.GetInterfaces - ' get the super class map if the object has multi-level inheritance - For n = 0 To interfaces.Length - 1 - m_classmap = getClassMap(interfaces(n).Name, interfaces(n).FullName) - If (Not m_classmap Is Nothing) AndAlso m_classmap.SuperClass Is Nothing Then - super = m_classmap - For m = n To interfaces.Length - 2 - interfaces(m) = interfaces(m + 1) - Next - If interfaces.Length > 1 Then - interfaces(m) = Nothing - End If - Exit For - End If - Next + ''----------------------------------------- + 'Dim n, m As Integer + 'Dim super As CClassMap - 'get actual interface which is the bottom level of inheritance - n = 0 - While n < interfaces.Length - 1 - If Not interfaces(n) Is Nothing Then - tmpCMap = getClassMap(interfaces(n).Name, interfaces(n).FullName) - If (Not tmpCMap Is Nothing) AndAlso tmpCMap.SuperClass Is super Then - super = tmpCMap - m_classmap = super - For m = n To interfaces.Length - 2 - interfaces(m) = interfaces(m + 1) - Next - interfaces(m) = Nothing + '' get the super class map if the object has multi-level inheritance + 'For n = 0 To interfaces.Length - 1 + ' m_classmap = getClassMap(interfaces(n).Name, interfaces(n).FullName) + ' If (Not m_classmap Is Nothing) AndAlso m_classmap.SuperClass Is Nothing Then + ' super = m_classmap + ' For m = n To interfaces.Length - 2 + ' interfaces(m) = interfaces(m + 1) + ' Next + ' If interfaces.Length > 1 Then + ' interfaces(m) = Nothing + ' End If + ' Exit For + ' End If + 'Next - If interfaces(0) Is Nothing Then - m_classmap = tmpCMap - Exit While - End If - n = 0 - Else - n = n + 1 - End If - Else - n = n + 1 - End If - End While + ''get actual interface which is the bottom level of inheritance + 'n = 0 + 'While n < interfaces.Length - 1 + ' If Not interfaces(n) Is Nothing Then + ' tmpCMap = getClassMap(interfaces(n).Name, interfaces(n).FullName) + ' If (Not tmpCMap Is Nothing) AndAlso tmpCMap.SuperClass Is super Then + ' super = tmpCMap + ' m_classmap = super + ' For m = n To interfaces.Length - 2 + ' interfaces(m) = interfaces(m + 1) + ' Next + ' interfaces(m) = Nothing + + ' If interfaces(0) Is Nothing Then + ' m_classmap = tmpCMap + ' Exit While + ' End If + ' n = 0 + ' Else + ' n = n + 1 + ' End If + ' Else + ' n = n + 1 + ' End If + 'End While End If If (m_classmap Is Nothing) Then Throw New NoClassMapException("No class map for " & m_object.GetType.FullName) End If - End If + 'End If Return m_classmap End Function @@ -496,10 +502,6 @@ Else pbroker = getPersistenceBrokerInstance() injobj = pbroker.getInjectedObject(obj) - If injobj Is Nothing Then - pbroker.StartTracking(obj) - injobj = pbroker.getInjectedObject(obj) - End If End If Return injobj End Function Index: CInjectedObjects.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CInjectedObjects.vb,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- CInjectedObjects.vb 28 Feb 2005 23:07:44 -0000 1.4 +++ CInjectedObjects.vb 11 Mar 2005 04:40:55 -0000 1.5 @@ -175,11 +175,19 @@ Public Overloads Function Find(ByVal obj As Object, ByVal useFindAttributes As Boolean) As CInjectedObject Dim injObj As CInjectedObject + If Not TypeOf (obj) Is CInjectedObject Then injObj = New CInjectedObject(obj) + Else + injObj = obj + End If Return Find(injObj, useFindAttributes) End Function Public Overloads Function Find(ByVal obj As CInjectedObject, ByVal useFindAttributes As Boolean) As CInjectedObject + Return Find(obj, useFindAttributes, True) + End Function + + Public Overloads Function Find(ByVal obj As CInjectedObject, ByVal useFindAttributes As Boolean, ByVal CheckSubClasses As Boolean) As CInjectedObject Dim injObj As CInjectedObject Dim x As DictionaryEntry Dim attrmap As CAttributeMap @@ -203,7 +211,7 @@ x = CType(m_Enumerator.Current, DictionaryEntry) injObj = CType(x.Value, CInjectedObject) t = injObj.GetObjectType - If t Is obj.GetObjectType Or t.IsSubclassOf(obj.GetObjectType) Then + If t Is obj.GetObjectType OrElse (CheckSubClasses AndAlso t.IsSubclassOf(obj.GetObjectType)) Then found = True Try If useFindAttributes Then Index: CClassMap.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CClassMap.vb,v retrieving revision 1.52 retrieving revision 1.53 diff -u -d -r1.52 -r1.53 --- CClassMap.vb 3 Mar 2005 00:38:23 -0000 1.52 +++ CClassMap.vb 11 Mar 2005 04:40:55 -0000 1.53 @@ -1428,7 +1428,18 @@ End If Catch ex As Exception End Try + Try obj.SetAttributeValue(AttrMap.Name, val) + Catch ex As Exception + Dim s As String + s = "Could not populate {0}.{1} with value {2}" + If val Is Nothing Then + s = String.Format(s, Me.Name, AttrMap.Name, "Nothing") + Else + s = String.Format(s, Me.Name, AttrMap.Name, val.ToString) + End If + Throw New RetrieveException(s, ex) + End Try If Not val Is Nothing AndAlso Not IsDBNull(val) Then obj.Persistent = True obj.State = PersistenceState.Persistent @@ -1524,7 +1535,18 @@ Catch ex As Exception End Try + Try obj.SetAttributeValue(AttrMap.Name, tmpObj) + Catch ex As Exception + Dim s As String + s = "Could not populate {0}.{1} with value {2}" + If tmpObj Is Nothing Then + s = String.Format(s, Me.Name, AttrMap.Name, "Nothing") + Else + s = String.Format(s, Me.Name, AttrMap.Name, tmpObj.ToString) + End If + Throw New RetrieveException(s, ex) + End Try If Not tmpObj Is Nothing AndAlso Not IsDBNull(tmpObj) Then obj.Persistent = True obj.State = PersistenceState.Persistent @@ -1590,7 +1612,18 @@ End If Catch ex As Exception End Try + Try obj.SetAttributeValue(AttrMap.Name, tmpObj) + Catch ex As Exception + Dim s As String + s = "Could not populate {0}.{1} with value {2}" + If tmpObj Is Nothing Then + s = String.Format(s, Me.Name, AttrMap.Name, "Nothing") + Else + s = String.Format(s, Me.Name, AttrMap.Name, tmpObj.ToString) + End If + Throw New RetrieveException(s, ex) + End Try If Not tmpObj Is Nothing AndAlso Not IsDBNull(tmpObj) Then obj.Persistent = True obj.State = PersistenceState.Persistent @@ -1626,7 +1659,18 @@ End If Catch ex As Exception End Try + Try obj.SetAttributeValue(AttrMap.Name, tmpObj) + Catch ex As Exception + Dim s As String + s = "Could not populate {0}.{1} with value {2}" + If tmpObj Is Nothing Then + s = String.Format(s, Me.Name, AttrMap.Name, "Nothing") + Else + s = String.Format(s, Me.Name, AttrMap.Name, tmpObj.ToString) + End If + Throw New RetrieveException(s, ex) + End Try If Not tmpObj Is Nothing AndAlso Not IsDBNull(tmpObj) Then obj.Persistent = True obj.State = PersistenceState.Persistent @@ -1886,8 +1930,6 @@ End If statement.addSqlClause(" " & am.ColumnMap.getAliasQualifiedName(mapName) _ & cm2.RelationalDatabase.getClauseStringEqualTo("_" & i.ToString & "_")) - 'statement.addSqlClause(" " & am.ColumnMap.getAliasQualifiedName(mapName) _ - ' & " = " & cm2.RelationalDatabase.getParamHolder(i)) Next i cm2 = Nothing Loop While Not cm2 Is Nothing @@ -1929,6 +1971,7 @@ Dim de As DictionaryEntry Dim isfirst As Boolean = True Dim am As CAttributeMap + Dim paramCount As Integer rMaps.Add("t1", Me) 'Joins are not depending on method used for retrieve (ie find or retrieve) so don't @@ -1979,11 +2022,13 @@ statement.addSqlClause(m_joinSet.GetSQLString) statement.addSqlClause(" " & Me.RelationalDatabase.getClauseStringWhere & " ") - Do + paramCount = 0 classMapCount = 1 + isfirst = True mapName = "t" & classMapCount.ToString cm2 = rMaps(mapName) - isfirst = True + Do + mapName = "t" & classMapCount.ToString If Not cm2.SharedTableField Is Nothing Then cm3 = cm2 While Not cm2 Is Nothing @@ -1998,7 +2043,7 @@ If cm2.SharedTableField Is Nothing Then cm2 = Nothing End While cm2 = cm3 - End If + Else For i = 1 To cm2.getFindSize am = cm2.FindAttributeMaps(i) If Not isfirst Then @@ -2006,12 +2051,13 @@ Else isfirst = False End If + paramCount += 1 statement.addSqlClause(" " & am.ColumnMap.getAliasQualifiedName(mapName) _ - & cm2.RelationalDatabase.getClauseStringEqualTo("_" & i.ToString & "_")) - 'statement.addSqlClause(" " & am.ColumnMap.getAliasQualifiedName(mapName) _ - ' & " = " & cm2.RelationalDatabase.getParamHolder(i)) + & cm2.RelationalDatabase.getClauseStringEqualTo("_" & paramCount.ToString & "_")) Next i - cm2 = Nothing + classMapCount += 1 + End If + cm2 = cm2.SuperClass Loop While Not cm2 Is Nothing m_sqlFindStub = statement.SqlString @@ -2115,9 +2161,7 @@ Try ip = CType(obj, IPersistableObject) Catch ex As Exception - pbroker = getPersistenceBrokerInstance() - 'pbroker.StartTracking(obj) - ip = pbroker.getInjectedObject(obj) + ip = New CInjectedObject(obj) End Try Return ip End Function @@ -2131,10 +2175,21 @@ Try ip = CType(obj, IPersistableObject) Catch ex As Exception - pbroker = getPersistenceBrokerInstance() - 'pbroker.StartTracking(obj) - ip = pbroker.getInjectedObject(obj) + ip = New CInjectedObject(obj) End Try Return ip End Function + + Friend Function IsChildOf(ByVal cm As CClassMap) As Boolean + Dim result As Boolean = False + Dim cm2 As CClassMap + cm2 = Me.SuperClass + While Not cm2 Is Nothing + If cm2.Equals(cm) Then + result = True + Exit While + End If + End While + Return result + End Function End Class \ No newline at end of file |