From: Richard B. <rb...@us...> - 2005-02-09 06:24:55
|
Update of /cvsroot/jcframework/dotnet In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29948 Modified Files: AToMSFramework.vbproj CClassMap.vb CCriteriaCondition.vb CInjectedObject.vb CJoin.vb CMultiSummaryCriteria.vb CPersistenceBroker.vb CPersistentObject.vb CSelectInCriteria.vb CUDAMap.vb CXMLConfigLoader.vb XMLMapping.xsd Added Files: CAssociationKey.vb CAssociationObject.vb CAssociationTable.vb Log Message: -- INCOMPLETE -- New code to allow associations to be declared as Many-To-Many without needing a class just to manage the association. Save and Retrieve works, haven't tested deletes or retrieve criteria yet Index: AToMSFramework.vbproj =================================================================== RCS file: /cvsroot/jcframework/dotnet/AToMSFramework.vbproj,v retrieving revision 1.22 retrieving revision 1.23 diff -u -d -r1.22 -r1.23 --- AToMSFramework.vbproj 7 Feb 2005 07:37:33 -0000 1.22 +++ AToMSFramework.vbproj 9 Feb 2005 06:24:44 -0000 1.23 @@ -109,6 +109,21 @@ BuildAction = "None" /> <File + RelPath = "CAssociationKey.vb" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "CAssociationObject.vb" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "CAssociationTable.vb" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "CAttributeMap.vb" SubType = "Code" BuildAction = "Compile" Index: CPersistenceBroker.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CPersistenceBroker.vb,v retrieving revision 1.91 retrieving revision 1.92 diff -u -d -r1.91 -r1.92 --- CPersistenceBroker.vb 7 Feb 2005 07:37:34 -0000 1.91 +++ CPersistenceBroker.vb 9 Feb 2005 06:24:44 -0000 1.92 @@ -287,6 +287,7 @@ Dim i As Integer Dim isfirst As Boolean = True Dim am As CAttributeMap + Dim fromClass, toClass As CClassMap cm = obj.GetClassMap @@ -406,11 +407,11 @@ If udamap.RetrieveAutomatic Then mapName = "t" & classMapCount.ToString classMapCount += 1 - cm2 = udamap.ForClass + cm2 = udamap.ToClass '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 - targetobj = obj.GetObjectByAttribute(udamap.Target) + 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 If cm2.ChildrenMaps.Count > 0 Then @@ -435,7 +436,7 @@ Catch End Try End If - obj.SetAttributeValue(udamap.Target, targetobj.GetSourceObject) + obj.SetAttributeValue(udamap.FromClassTarget, targetobj.GetSourceObject) If Not targetobj.AssociationsLoaded Then If udamap.LazyLoad Then targetobj.IsDirty = False @@ -453,10 +454,10 @@ End If If Not gotValue Then 'Check whether the object is of child type - If udamap.ForClass.ChildrenMaps.Count > 0 Then - targetobj = Me.createTargetObjectForMultipleInheritance(udamap.ForClass, obj.GetObjectType, obj.GetObjectType.Namespace, rs.ResultSet.Tables(0).Rows(i), joins, conn) + 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.ForClass) + 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 @@ -487,12 +488,12 @@ targetobj.IsDirty = False targetobj.OriginalCacheKey = New CCacheKey(targetobj) End If - obj.SetAttributeValue(udamap.Target, targetobj.GetSourceObject) + obj.SetAttributeValue(udamap.FromClassTarget, targetobj.GetSourceObject) End If Else 'Object doesn't exist - let's create it 'See if the assembly path is specified - targetobj = udamap.ForClass.CreateObjectInstance + targetobj = udamap.ToClass.CreateObjectInstance If Not targetobj Is Nothing Then cm2.populateObject(cm2, targetobj, rs, mapName) @@ -524,19 +525,33 @@ targetobj.IsDirty = False targetobj.OriginalCacheKey = New CCacheKey(targetobj) End If - obj.SetAttributeValue(udamap.Target, targetobj.GetSourceObject) + obj.SetAttributeValue(udamap.FromClassTarget, targetobj.GetSourceObject) End If End If End If End If - ElseIf udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Then - col = obj.GetCollectionByAttribute(udamap.Target) + ElseIf udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Or udamap.Cardinality = CUDAMap.CardinalityEnum.MANY_TO_MANY Then + If udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Then + col = obj.GetCollectionByAttribute(udamap.FromClassTarget) + fromClass = udamap.FromClass + toClass = udamap.ToClass + Else + If obj.GetClassMap.Name = udamap.FromClass.Name Then + col = obj.GetCollectionByAttribute(udamap.FromClassTarget) + fromClass = udamap.FromClass + toClass = udamap.ToClass + Else + col = obj.GetCollectionByAttribute(udamap.ToClassTarget) + toClass = udamap.FromClass + fromClass = udamap.ToClass + End If + End If 'Check whether the object is of child type - If udamap.ForClass.ChildrenMaps.Count > 0 Then - targetobj = Me.createTargetObjectForMultipleInheritance(udamap.ForClass, obj.GetObjectType, obj.GetObjectType.Namespace, rs.ResultSet.Tables(0).Rows(i), joins, conn) + If fromClass.ChildrenMaps.Count > 0 Then + targetobj = Me.createTargetObjectForMultipleInheritance(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.ForClass) + classMapCount += Me.getChildCountForMultipleInheritance(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) @@ -588,8 +603,7 @@ End If End If Else - targetobj = udamap.ForClass.CreateObjectInstance - + targetobj = toClass.CreateObjectInstance rw = rs.ResultSet.Tables(0).Rows(i) cm2.populateObject(cm2, targetobj, rw, mapName) If targetobj.Persistent Then @@ -701,9 +715,9 @@ udaMap = cm.AssociationMaps.Item(myKeys(i)) If udaMap.RetrieveAutomatic Then aCriteria = New CRetrieveCriteria - aCriteria.ClassMap = udaMap.ForClass + aCriteria.ClassMap = udaMap.ToClass If udaMap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_ONE Then - Value = obj.GetObjectByAttribute(udaMap.Target) + Value = obj.GetObjectByAttribute(udaMap.FromClassTarget) gotValue = False If Not Value Is Nothing Then 'Need to know if returned object is persistent and has a legitimate key @@ -717,14 +731,14 @@ Value = anObjPers Value.IsDirty = False Value.OriginalCacheKey = New CCacheKey(Value) - obj.SetAttributeValue(udaMap.Target, Value.GetSourceObject) + obj.SetAttributeValue(udaMap.FromClassTarget, Value.GetSourceObject) gotValue = True End If End If End If If Not gotValue Then 'Object doesn't exist - let's create it - Value = udaMap.ForClass.CreateObjectInstance + Value = udaMap.ToClass.CreateObjectInstance If Not Value Is Nothing Then 'Loop through fields in the association For j = 1 To udaMap.getSize @@ -745,12 +759,12 @@ End Try End If If found Then - Value.IsDirty = False 'After populating a new object - Value.OriginalCacheKey = New CCacheKey(Value) - obj.SetAttributeValue(udaMap.Target, Value.GetSourceObject) + Value.IsDirty = False 'After populating a new object + Value.OriginalCacheKey = New CCacheKey(Value) + obj.SetAttributeValue(udaMap.FromClassTarget, Value.GetSourceObject) + End If End If End If - End If ElseIf udaMap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Then For j = 1 To udaMap.getSize ValueVar = cm.getValueForRelationalDatabase(obj.GetValueByAttribute(udaMap.getEntry(j).FromAttrMap.Name)) @@ -758,23 +772,23 @@ Next j aCriteria.ReturnFullObjects = Not udaMap.LazyLoad cursor = processCriteria(aCriteria, colCriteriaParameters, conn) - col = obj.GetCollectionByAttribute(udaMap.Target) + col = obj.GetCollectionByAttribute(udaMap.FromClassTarget) If col Is Nothing Then - Throw New RetrieveException("Collection " & udaMap.Target & " is not initialised for " & obj.GetObjectType.ToString) + Throw New RetrieveException("Collection " & udaMap.FromClassTarget & " is not initialised for " & obj.GetObjectType.ToString) End If col.Clear() 'Clear the collection before polpulating, just to be sure While cursor.hasElements And Not cursor.EOF - Value = udaMap.ForClass.CreateObjectInstance + Value = udaMap.ToClass.CreateObjectInstance anObjPers = Value If udaMap.LazyLoad Then cursor.loadProxy(anObjPers.GetSourceObject) Else - cursor.loadObject(anObjPers.GetSourceObject) - 'To prevent recursive associations causing problems we need to add the - 'object to the cache here as a preliminary measure - m_cache.Add(anObjPers) - retrieveAssociations(anObjPers, conn, anObjPers.GetClassMap, useCache) + cursor.loadObject(anObjPers.GetSourceObject) + 'To prevent recursive associations causing problems we need to add the + 'object to the cache here as a preliminary measure + m_cache.Add(anObjPers) + retrieveAssociations(anObjPers, conn, anObjPers.GetClassMap, useCache) End If anObjPers.IsDirty = False 'After populating a new object anObjPers.OriginalCacheKey = New CCacheKey(anObjPers) @@ -844,6 +858,33 @@ End SyncLock End Sub + Friend Sub saveAssociationObject(ByRef obj As CAssociationObject) + SyncLock GetType(CPersistenceBroker) + Dim inTicks As Long, outTicks As Long + inTicks = Now.Ticks + + Dim cm As CClassMap = obj.ClassMapA + Dim conn As _CConnection = cm.RelationalDatabase.getConnection(Nothing) + Try + conn.startTransaction() + conn.AutoCommit = False + savePrivateAssociationObject(obj, conn) + conn.commit() + Catch ex As Exception + conn.rollback() + cm.RelationalDatabase.freeConnection(conn) + Throw New SaveException(ex.Message, ex) + End Try + cm.RelationalDatabase.freeConnection(conn) + outTicks = Now.Ticks + Try + PCAverageTime.RawValue = outTicks - inTicks + PCAverageTimeBase.Increment() + Catch + End Try + End SyncLock + End Sub + '''----------------------------------------------------------------------------- ''' <summary> ''' Method to actually save (persist) an object. @@ -933,6 +974,39 @@ End If End Sub + Private Sub savePrivateAssociationObject(ByRef obj As CAssociationObject, ByVal conn As _CConnection) + Dim statement As CSqlStatement + Dim i As Integer + Dim objACol As Collection + Dim objBCol As Collection + Dim doDelete As Boolean + Dim attrMap As CAttributeMap + Dim Value, Value2 As Object + + Debug.WriteLine("Saving many-to-many association object " & obj.Association.AssocationTable.Name) + + If obj.DeleteNeeded Then + Try + statement = obj.getDeleteSqlUsingOriginalValues() + conn.processStatement(statement) + Catch + End Try + End If + + Try + statement = obj.getInsertSql + conn.processStatement(statement) + Catch ex As Exception + End Try + + Try + PCSQLHits.Increment() + PCInserts.Increment() + Catch + End Try + End Sub + + '''----------------------------------------------------------------------------- ''' <summary> ''' Deletes an object from the database. Does not delete the parent object(s). @@ -973,7 +1047,7 @@ Try deletePrivateObject(obj, conn, deleteSuperClass) conn.commit() - Catch ex As Exception + Catch ex As Exception x = New DeleteException(ex.Message, ex) conn.rollback() Finally @@ -988,7 +1062,7 @@ If Not x Is Nothing Then Throw x End If - End Try + End Try End SyncLock End Sub @@ -1062,7 +1136,7 @@ If udaMap.DeleteAutomatic Then For j = 1 To udaMap.getSize If udaMap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_ONE Then - Value = obj.GetObjectByAttribute(udaMap.Target) + Value = obj.GetObjectByAttribute(udaMap.FromClassTarget) If Not Value Is Nothing Then If retrieveObject(Value, False, True) Then 'If Value.Retrieve() Then @@ -1070,7 +1144,7 @@ End If End If ElseIf udaMap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Then - col = obj.GetCollectionByAttribute(udaMap.Target) + col = obj.GetCollectionByAttribute(udaMap.FromClassTarget) If Not col Is Nothing Then For k = 0 To col.Count - 1 If col.Item(k).GetType.IsSubclassOf(GetType(CPersistentObject)) Then @@ -1819,9 +1893,9 @@ Return cursor Catch - firstClassMap.RelationalDatabase.freeConnection(conn) - Return Nothing - End Try + firstClassMap.RelationalDatabase.freeConnection(conn) + Return Nothing + End Try End Function @@ -2191,8 +2265,8 @@ fromClassMap = m_classMaps.Item(types(i).Name) toClassMap = m_classMaps.Item(afAssociation.TargetClass.Name) udaAm = New CUDAMap - udaAm.ForClass = toClassMap - udaAm.Target = afAssociation.TargetProperty + udaAm.ToClass = toClassMap + udaAm.FromClassTarget = afAssociation.TargetProperty udaAm.DeleteAutomatic = afAssociation.Delete udaAm.SaveAutomatic = afAssociation.Save udaAm.RetrieveAutomatic = afAssociation.Retrieve @@ -2201,11 +2275,10 @@ udaAm.RetrieveAutomatic = True End If If afAssociation.Name Is Nothing OrElse afAssociation.Name = [String].Empty Then - udaAm.Name = udaAm.Target + udaAm.Name = udaAm.FromClassTarget Else udaAm.Name = afAssociation.Name End If - udaAm.Inverse = False udaAm.Cardinality = afAssociation.Cardinality att = types(i).GetCustomAttributes(GetType(AFAssociationEntryAttribute), False) If att.Length > 0 Then @@ -2387,11 +2460,13 @@ Dim de As DictionaryEntry Dim udamap As CUDAMap Dim value, o As IPersistableObject + Dim qObj As Object Dim col As IList 'Dim stack As New Stack Dim queue As New Queue Dim i, k As Integer Dim tmpObj As Object + Dim aObj As CAssociationObject If obj.IsQueued Then 'if an object has already been added to the save queue, there is no need to add @@ -2414,9 +2489,6 @@ If Not obj.IsDirty Then Return queue 'Do not save if nothing changed End If If obj.IsProxy Then Return queue 'Do not save if object is proxied - 'If obj.GetObjectType.IsSubclassOf(GetType(CPersistentObject)) Then - ' If Not CType(obj, CPersistentObject).IsValid Then Return queue 'Do not save if object is not valid - 'End If If GetType(IValidation).IsInstanceOfType(obj.GetSourceObject) Then If Not CType(obj.GetSourceObject, IValidation).IsValid Then Return queue 'Do not save if object is not valid End If @@ -2427,7 +2499,6 @@ Return queue End If If includeBaseObject Then - 'obj.IsDirty = False 'Added to queue so clear dirty flag queue.Enqueue(obj) End If Else @@ -2459,14 +2530,14 @@ udamap = cm.getStraightAssociationMap(i) If udamap.SaveAutomatic Then If udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_ONE Then - value = obj.GetObjectByAttribute(udamap.Target) + value = obj.GetObjectByAttribute(udamap.FromClassTarget) If Not value Is Nothing Then For Each o In getObjectsToSave(value, True, checkAssociationsRecursivly) queue.Enqueue(o) Next End If ElseIf udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Then - col = obj.GetCollectionByAttribute(udamap.Target) + col = obj.GetCollectionByAttribute(udamap.FromClassTarget) If Not col Is Nothing Then For k = 0 To col.Count() - 1 tmpObj = col.Item(k) @@ -2480,22 +2551,14 @@ Next Next k End If - End If - End If - Next i - - For i = 1 To cm.getInverseAssociationMapSize - udamap = cm.getInverseAssociationMap(i) - If udamap.SaveAutomatic Then - If udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_ONE Then - value = obj.GetObjectByAttribute(udamap.Target) - If Not value Is Nothing Then - For Each o In getObjectsToSave(value, True, checkAssociationsRecursivly) - queue.Enqueue(o) - Next + ElseIf udamap.Cardinality = CUDAMap.CardinalityEnum.MANY_TO_MANY Then + If obj.GetClassMap.Name = udamap.FromClass.Name Then + col = obj.GetCollectionByAttribute(udamap.FromClassTarget) + Else + If Not udamap.ToClassTarget Is Nothing Then + col = obj.GetCollectionByAttribute(udamap.ToClassTarget) + End If End If - ElseIf udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Then - col = obj.GetCollectionByAttribute(udamap.Target) If Not col Is Nothing Then For k = 0 To col.Count() - 1 tmpObj = col.Item(k) @@ -2504,8 +2567,21 @@ Else value = tmpObj End If - For Each o In getObjectsToSave(value, True, checkAssociationsRecursivly) - queue.Enqueue(o) + aObj = Nothing + For Each qObj In getObjectsToSave(value, True, checkAssociationsRecursivly) + queue.Enqueue(qObj) + If aObj Is Nothing AndAlso value.Equals(qObj) Then + 'since we are saving this object (obj) and one of the objects in the association + 'we need to ensure the association table gets updated. This will be done via + 'the CAssociationObject class. We need to create an object here for the class. + aObj = New CAssociationObject + aObj.ObjectA = obj + aObj.ObjectB = value + aObj.ClassMapA = obj.GetClassMap + aObj.ClassMapB = value.GetClassMap + aObj.Association = udamap + queue.Enqueue(aObj) + End If Next Next k End If @@ -2939,7 +3015,7 @@ PCAverageTimeBase.RawValue = 0 Catch ex As Exception Trace.WriteLine("Could not create performance counters. If using ASP.NET please see http://objectsharp.com/Blogs/bruce/archive/2003/12/05/222.aspx" & _ - vbCrLf & ex.Message) + vbCrLf & ex.Message) End Try End Sub End Class \ No newline at end of file Index: CXMLConfigLoader.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CXMLConfigLoader.vb,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- CXMLConfigLoader.vb 7 Feb 2005 07:37:35 -0000 1.30 +++ CXMLConfigLoader.vb 9 Feb 2005 06:24:45 -0000 1.31 @@ -137,12 +137,12 @@ '''----------------------------------------------------------------------------- Private Sub IConfigLoader_loadConfig(ByRef dbMap As HybridDictionary, ByRef clMap As HybridDictionary) Implements _IConfigLoader.loadConfig m_classMap = clMap - m_databaseMap = dbMap - 'Specifically clear database and class maps - dbMap.Clear() - clMap.Clear() + m_databaseMap = dbMap + 'Specifically clear database and class maps + dbMap.Clear() + clMap.Clear() - Dim doc As New XmlDocument + Dim doc As New XmlDocument Try doc.Load(Me.FileName) @@ -164,14 +164,14 @@ If node.NodeType = XmlNodeType.Element Then elem = node If node.Name = "database" Then - reldb = getRelationalDatabase(elem) - Try - dbMap.Add(reldb.Name, reldb) - Catch ex As Exception - Throw New AToMSFramework.XMLMappingException("Could not add database " & reldb.Name & vbCrLf & ex.Message, ex) - End Try - ElseIf node.Name = "class" Then - clm = getClassMap(elem) + reldb = getRelationalDatabase(elem) + Try + dbMap.Add(reldb.Name, reldb) + Catch ex As Exception + Throw New AToMSFramework.XMLMappingException("Could not add database " & reldb.Name & vbCrLf & ex.Message, ex) + End Try + ElseIf node.Name = "class" Then + clm = getClassMap(elem) If clm.ClassNameSpace <> String.Empty Then keyStr = clm.ClassNameSpace & "." & clm.Name Else @@ -182,10 +182,10 @@ Catch ex As Exception Throw New AToMSFramework.XMLMappingException("Could not add classmap " & clm.Name & vbCrLf & ex.Message, ex) End Try - ElseIf node.Name = "association" Then - processAssociation(elem) - End If - End If + ElseIf node.Name = "association" Then + processAssociation(elem) + End If + End If node = node.NextSibling() End While @@ -275,10 +275,10 @@ ''' </history> '''----------------------------------------------------------------------------- Private Function getClassMap(ByVal node As XmlElement) As CClassMap - Dim attrClassName As XmlAttribute, attrTable As XmlAttribute, attrTableOwner As XmlAttribute - Dim attrDatabase As XmlAttribute, attrSuperClassName As XmlAttribute, attrReadOnly As XmlAttribute, attrModifyOnly As XmlAttribute + Dim attrClassName As XmlAttribute, attrTable As XmlAttribute, attrTableOwner As XmlAttribute + Dim attrDatabase As XmlAttribute, attrSuperClassName As XmlAttribute, attrReadOnly As XmlAttribute, attrModifyOnly As XmlAttribute Dim attrClassNameSpace, attrAssemblyPath, attrSuperClassNameSpace As XmlAttribute - Dim attrSharedField As XmlAttribute, attrSharedValue As XmlAttribute + Dim attrSharedField As XmlAttribute, attrSharedValue As XmlAttribute Dim attrClassFactory As XmlAttribute attrClassName = node.GetAttributeNode("name") attrTable = node.GetAttributeNode("table") @@ -425,8 +425,8 @@ colMap.IsNullable = cc.Item(ClassMap.SharedTableField & "NL") Catch Throw New NoColumnException("Error retrieving storage information for column " _ - + ClassMap.SharedTableField + " in class " + ClassMap.Name _ - + ". Please check the shared table field in the mapping.") + + ClassMap.SharedTableField + " in class " + ClassMap.Name _ + + ". Please check the shared table field in the mapping.") End Try ClassMap.SharedTableColumnMap = colMap End If @@ -548,40 +548,47 @@ ''' </history> '''----------------------------------------------------------------------------- Private Sub processAssociation(ByVal node As XmlElement) - Dim attrToClass, attrFromClass, attrTarget As Object + Dim attrToClass, attrFromClass As XmlAttribute + Dim attrFromTarget, attrToTarget As XmlAttribute Dim attrCardinality As XmlAttribute + Dim attrName, attrOwner As XmlAttribute + Dim attrFromClassNameSpace As XmlAttribute + Dim attrToClassNameSpace As XmlAttribute + Dim attrFromAttribute As XmlAttribute + Dim attrToAttribute As XmlAttribute + Dim attrColumn As XmlAttribute Dim fromClassMap As CClassMap Dim toClassMap As CClassMap Dim udaAm As CUDAMap - Dim nodeChild As XmlNode - Dim elementChild As XmlElement + Dim nodeChild, nodeChild2 As XmlNode + Dim elementChild, elementChild2 As XmlElement Dim entry As CUDAMapEntry - Dim amFromAttribute As Object + Dim amFromAttribute As CAttributeMap Dim amToAttribute As CAttributeMap - Dim attrFromAttribute As Object - Dim attrToAttribute As XmlAttribute - Dim attrName As XmlAttribute - Dim attrFromClassNameSpace As XmlAttribute - Dim attrToClassNameSpace As XmlAttribute + Dim assocTable As CAssociationTable + Dim assocKey As CAssociationKey Dim keyStr As String Dim tmpStr As String attrFromClass = node.GetAttributeNode("fromClass") attrToClass = node.GetAttributeNode("toClass") - attrTarget = node.GetAttributeNode("target") + attrFromTarget = node.GetAttributeNode("target") + If attrFromTarget Is Nothing Then + attrFromTarget = node.GetAttributeNode("fromClassTarget") + End If + attrToTarget = node.GetAttributeNode("toClassTarget") attrCardinality = node.GetAttributeNode("cardinality") attrName = node.GetAttributeNode("name") attrFromClassNameSpace = node.GetAttributeNode("fromClassNameSpace") attrToClassNameSpace = node.GetAttributeNode("toClassNameSpace") - If ((Not attrFromClass Is Nothing) And (Not attrToClass Is Nothing) And (Not attrTarget Is Nothing)) Then + If ((Not attrFromClass Is Nothing) And (Not attrToClass Is Nothing) And (Not attrFromTarget Is Nothing)) Then If Not attrToClassNameSpace Is Nothing AndAlso Not attrFromClassNameSpace.Value Is Nothing Then keyStr = attrFromClassNameSpace.Value & "." & attrFromClass.Value Else keyStr = attrFromClass.Value End If fromClassMap = m_classMap.Item(keyStr) - 'fromClassMap = m_classMap.Item(attrFromClass.Value) If fromClassMap Is Nothing Then Throw New XMLMappingException("Error in association definition: fromClassMap = " + attrFromClass.Value) End If @@ -592,14 +599,16 @@ keyStr = attrToClass.Value End If toClassMap = m_classMap.Item(keyStr) - 'toClassMap = m_classMap.Item(attrToClass.Value) If toClassMap Is Nothing Then Throw New XMLMappingException("Error in association definition: toClassMap = " + attrToClass.Value) End If udaAm = New CUDAMap udaAm.FromClass = fromClassMap - udaAm.ForClass = toClassMap - udaAm.Target = attrTarget.Value + udaAm.toclass = toClassMap + udaAm.FromClassTarget = attrFromTarget.Value + If Not attrToTarget Is Nothing Then + udaAm.ToClassTarget = attrToTarget.Value + End If udaAm.DeleteAutomatic = node.GetAttributeNode("deleteAutomatic").Value udaAm.SaveAutomatic = node.GetAttributeNode("saveAutomatic").Value tmpStr = node.GetAttributeNode("retrieveAutomatic").Value @@ -612,18 +621,17 @@ udaAm.RetrieveAutomatic = False End If If attrName Is Nothing Then - udaAm.Name = udaAm.Target + udaAm.Name = udaAm.FromClassTarget Else udaAm.Name = attrName.Value End If - If Not node.GetAttribute("inverse") Is Nothing Then - udaAm.Inverse = node.GetAttributeNode("inverse").Value - End If If Not attrCardinality Is Nothing Then If UCase(attrCardinality.Value) = "ONETOONE" Then udaAm.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_ONE ElseIf UCase(attrCardinality.Value) = "ONETOMANY" Then udaAm.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY + ElseIf UCase(attrCardinality.Value) = "MANYTOMANY" Then + udaAm.Cardinality = CUDAMap.CardinalityEnum.MANY_TO_MANY End If End If @@ -631,6 +639,7 @@ Do While Not nodeChild Is Nothing If nodeChild.NodeType = XmlNodeType.Element Then elementChild = nodeChild + 'process association map entries If elementChild.Name = "entry" Then attrFromAttribute = elementChild.GetAttributeNode("fromAttribute") attrToAttribute = elementChild.GetAttributeNode("toAttribute") @@ -652,22 +661,81 @@ Throw New XMLMappingException("Error in association definition") End If entry = New CUDAMapEntry - If udaAm.Inverse Then - entry.FromAttrMap = amToAttribute - entry.ToAttrMap = amFromAttribute - Else - entry.FromAttrMap = amFromAttribute - entry.ToAttrMap = amToAttribute - End If + entry.FromAttrMap = amFromAttribute + entry.ToAttrMap = amToAttribute udaAm.addEntry(entry) End If + ElseIf elementChild.Name = "associationTable" Then + assocTable = New CAssociationTable + attrName = elementChild.GetAttributeNode("name") + attrOwner = elementChild.GetAttributeNode("owner") + If Not attrName Is Nothing Then + assocTable.Name = attrName.Value + If Not attrOwner Is Nothing Then + assocTable.TableOwner = attrOwner.Value + End If + nodeChild2 = elementChild.FirstChild + Do While Not nodeChild2 Is Nothing + If nodeChild2.NodeType = XmlNodeType.Element Then + elementChild2 = nodeChild2 + 'process association map entries + If elementChild2.Name = "fromClassKey" Then + attrName = elementChild2.GetAttributeNode("name") + attrColumn = elementChild2.GetAttributeNode("column") + If Not attrName Is Nothing And Not attrColumn Is Nothing Then + assocKey = New CAssociationKey + assocKey.AttributeMap = fromClassMap.getAttributeMapByString(attrName.Value, False) + assocKey.ColumnMap = New CColumnMap + With assocKey.ColumnMap + .IsFind = False + .IsIdentity = False + .IsNullable = False + .Name = attrColumn.Value + 'Assume that dbtypes in the mapping table match dbtypes of data table + .ProviderType = assocKey.AttributeMap.ColumnMap.ProviderType + .StorageSize = assocKey.AttributeMap.ColumnMap.StorageSize + .StorageType = assocKey.AttributeMap.ColumnMap.StorageType + .TableMap = New CTableMap + .TableMap.Name = assocTable.Name + .TableMap.TableOwner = assocTable.TableOwner + End With + assocTable.FromKeys.Add(assocKey) + End If + ElseIf elementChild2.Name = "toClassKey" Then + attrName = elementChild2.GetAttributeNode("name") + attrColumn = elementChild2.GetAttributeNode("column") + If Not attrName Is Nothing And Not attrColumn Is Nothing Then + assocKey = New CAssociationKey + assocKey.AttributeMap = toClassMap.getAttributeMapByString(attrName.Value, False) + assocKey.ColumnMap = New CColumnMap + With assocKey.ColumnMap + .IsFind = False + .IsIdentity = False + .IsNullable = False + .Name = attrColumn.Value + .ProviderType = assocKey.AttributeMap.ColumnMap.ProviderType + .StorageSize = assocKey.AttributeMap.ColumnMap.StorageSize + .StorageType = assocKey.AttributeMap.ColumnMap.StorageType + End With + assocTable.ToKeys.Add(assocKey) + End If + End If + End If + nodeChild2 = nodeChild2.NextSibling + Loop + udaAm.AssocationTable = assocTable End If + End If End If nodeChild = nodeChild.NextSibling Loop fromClassMap.addAssociationMap(udaAm) + 'Many to many associations need to be added to both class maps + If udaAm.Cardinality = CUDAMap.CardinalityEnum.MANY_TO_MANY AndAlso Not udaAm.ToClassTarget Is Nothing Then + toClassMap.addAssociationMap(udaAm) + End If Else - Throw New XMLMappingException([String].Format("Error in association definition: Missing FromClass({0}), ToClass({1}) or Target({2}) attributes", attrFromClass, attrToClass, attrTarget)) + Throw New XMLMappingException([String].Format("Error in association definition: Missing FromClass({0}), ToClass({1}) or Target({2}) attributes", attrFromClass, attrToClass, attrFromTarget)) End If End Sub End Class \ No newline at end of file --- NEW FILE: CAssociationTable.vb --- Public Class CAssociationTable Private m_name As String Private m_owner As String Private m_fromKeys As New CAssociationKeys Private m_toKeys As New CAssociationKeys Public Property Name() As String Get Return m_Name End Get Set(ByVal Value As String) m_Name = Value End Set End Property Public Property TableOwner() As String Get Return m_owner End Get Set(ByVal Value As String) m_owner = Value End Set End Property Public Property FromKeys() As CAssociationKeys Get Return m_fromKeys End Get Set(ByVal Value As CAssociationKeys) m_fromKeys = Value End Set End Property Public Property ToKeys() As CAssociationKeys Get Return m_toKeys End Get Set(ByVal Value As CAssociationKeys) m_toKeys = Value End Set End Property End Class Index: CJoin.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CJoin.vb,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- CJoin.vb 15 Dec 2004 23:46:11 -0000 1.10 +++ CJoin.vb 9 Feb 2005 06:24:44 -0000 1.11 @@ -275,6 +275,9 @@ Dim leftBracket As String = "(" Dim rightBracket As String = ")" Dim isFirst As Boolean = True + Dim wrkAlias As String + Dim wrkKey As CAssociationKey + Dim fromKeys, toKeys As CAssociationKeys If LeftSide Is Nothing Then tm = CType(RightSide.Tables.Item(1), CTableMap) @@ -294,10 +297,8 @@ If i > 1 Then s = s & " " & db.getClauseStringAnd & " " End If - 's = s & cm.getReferenceAttributeMap(i).ColumnMap.getAliasQualifiedName(LeftSide.RootTableAlias) _ - ' & " = " & cm.getReferenceAttributeMap(i).AttributeMap.ColumnMap.getAliasQualifiedName(TableAlias) s = s & cm.getReferenceAttributeMap(i).ColumnMap.getAliasQualifiedName(LeftTableAlias) _ - & " = " & cm.getReferenceAttributeMap(i).AttributeMap.ColumnMap.getAliasQualifiedName(TableAlias) + & " = " & cm.getReferenceAttributeMap(i).AttributeMap.ColumnMap.getAliasQualifiedName(TableAlias) Next i s = s & rightBracket ElseIf Association Is Nothing Then @@ -328,19 +329,58 @@ rightBracket = "" End If tm = CType(cm.Tables.Item(1), CTableMap) - s = leftBracket & LeftSide.GetSQLString & " " & db.getClauseStringLeftJoin _ - & " " & db.getClauseStringTableAlias(tm.Name, tm.TableOwner, TableAlias) & " " & db.getClauseStringOn & " " - For i = 1 To CType(Association.Entries.Count, Short) - If i > 1 Then - s = s & " " & db.getClauseStringAnd & " " - End If - udaEntry = Association.getEntry(i) - 's = s & udaEntry.FromAttrMap.ColumnMap.getAliasQualifiedName(LeftSide.RootTableAlias) & " = " _ - '& udaEntry.ToAttrMap.ColumnMap.getAliasQualifiedName(TableAlias) - s = s & udaEntry.FromAttrMap.ColumnMap.getAliasQualifiedName(LeftTableAlias) & " = " _ + 'if one-to-many or one-to-one association code stays as it was + If Association.Cardinality <> CUDAMap.CardinalityEnum.MANY_TO_MANY Then + s = leftBracket & LeftSide.GetSQLString & " " & db.getClauseStringLeftJoin _ + & " " & db.getClauseStringTableAlias(tm.Name, tm.TableOwner, TableAlias) & " " & db.getClauseStringOn & " " + For i = 1 To CType(Association.Entries.Count, Short) + If i > 1 Then + s = s & " " & db.getClauseStringAnd & " " + End If + udaEntry = Association.getEntry(i) + s = s & udaEntry.FromAttrMap.ColumnMap.getAliasQualifiedName(LeftTableAlias) & " = " _ & udaEntry.ToAttrMap.ColumnMap.getAliasQualifiedName(TableAlias) - Next i - s = s & rightBracket + Next i + s = s & rightBracket + Else + 'Many to many joins must first join with the association table + 'We will append an 'x' to the alias for unique table names + + 'First determine which key set should be used (ie is this the association from or to class) + If Association.FromClass.Name = m_rightSide.Name Then + toKeys = Association.AssocationTable.FromKeys + fromKeys = Association.AssocationTable.ToKeys + Else + fromKeys = Association.AssocationTable.FromKeys + toKeys = Association.AssocationTable.ToKeys + End If + + 'Also we need to prepend two left brackets since we are adding two joins + s = leftBracket & leftBracket & LeftSide.GetSQLString & " " & db.getClauseStringLeftJoin + 'Add the association table + wrkAlias = TableAlias & "x" + s &= " " & db.getClauseStringTableAlias(Association.AssocationTable.Name, Association.AssocationTable.TableOwner, wrkAlias) & " " & db.getClauseStringOn & " " + For i = 1 To CType(fromKeys.Count, Short) + If i > 1 Then + s = s & " " & db.getClauseStringAnd & " " + End If + wrkKey = fromKeys.Item(i - 1) + s &= wrkKey.AttributeMap.ColumnMap.getAliasQualifiedName(LeftTableAlias) & " = " _ + & wrkAlias & "." & wrkKey.ColumnMap.Name + Next i + + 'Now add the class + s &= rightBracket & " " & db.getClauseStringLeftJoin + s &= " " & db.getClauseStringTableAlias(tm.Name, tm.TableOwner, TableAlias) & " " & db.getClauseStringOn & " " + For i = 1 To CType(toKeys.Count, Short) + If i > 1 Then + s = s & " " & db.getClauseStringAnd & " " + End If + wrkKey = toKeys.Item(i - 1) + s &= wrkAlias & "." & wrkKey.ColumnMap.Name & " = " & wrkKey.AttributeMap.ColumnMap.getAliasQualifiedName(TableAlias) + Next i + s = s & rightBracket + End If End If End If Return s Index: CInjectedObject.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CInjectedObject.vb,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- CInjectedObject.vb 4 Feb 2005 04:39:20 -0000 1.10 +++ CInjectedObject.vb 9 Feb 2005 06:24:44 -0000 1.11 @@ -583,9 +583,9 @@ udamap = classMap.getStraightAssociationMap(i) 'If udamap.SaveAutomatic Then If udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_ONE Then - obj.SetAttributeValue(udamap.Target, Me.getObjectByAttribute(udamap.Target)) - ElseIf udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Then - obj.SetAttributeValue(udamap.Target, Me.getCollectionByAttribute(udamap.Target)) + obj.SetAttributeValue(udamap.FromClassTarget, Me.getObjectByAttribute(udamap.FromClassTarget)) + ElseIf udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Or udamap.Cardinality = CUDAMap.CardinalityEnum.MANY_TO_MANY Then + obj.SetAttributeValue(udamap.FromClassTarget, Me.getCollectionByAttribute(udamap.FromClassTarget)) End If 'End If Next i @@ -603,9 +603,9 @@ udamap = cm.getStraightAssociationMap(i) 'If udamap.SaveAutomatic Then If udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_ONE Then - obj.SetAttributeValue(udamap.Target, Me.getObjectByAttribute(udamap.Target)) - ElseIf udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Then - obj.SetAttributeValue(udamap.Target, Me.getCollectionByAttribute(udamap.Target)) + obj.SetAttributeValue(udamap.FromClassTarget, Me.getObjectByAttribute(udamap.FromClassTarget)) + ElseIf udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Or udamap.Cardinality = CUDAMap.CardinalityEnum.MANY_TO_MANY Then + obj.SetAttributeValue(udamap.FromClassTarget, Me.getCollectionByAttribute(udamap.FromClassTarget)) End If 'End If Next i Index: CClassMap.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CClassMap.vb,v retrieving revision 1.48 retrieving revision 1.49 diff -u -d -r1.48 -r1.49 --- CClassMap.vb 19 Dec 2004 22:43:17 -0000 1.48 +++ CClassMap.vb 9 Feb 2005 06:24:44 -0000 1.49 @@ -41,7 +41,6 @@ Private m_associationMaps As HybridDictionary Private m_relationalDatabase As _CRelationalDatabase Private m_superClass As CClassMap - Private m_inverseAssociationMaps As Collection Private m_straightAssociationMaps As Collection Private m_findAttributeMaps As Collection Private m_identityAttributeMaps As Collection @@ -402,26 +401,6 @@ '''----------------------------------------------------------------------------- ''' <summary> - ''' Collection of inverse associations - ''' </summary> - ''' <value>A collection of assocation maps</value> - ''' <remarks>This collection contains all of the associations marked as Inverse="True" in - ''' the XML mapping.</remarks> - ''' <history> - ''' [rbanks] 27/11/2003 Created - ''' </history> - '''----------------------------------------------------------------------------- - Public Property InverseAssociationMaps() As Collection - Get - InverseAssociationMaps = m_inverseAssociationMaps - End Get - Set(ByVal Value As Collection) - m_inverseAssociationMaps = Value - End Set - End Property - - '''----------------------------------------------------------------------------- - ''' <summary> ''' Indicates whether the class is marked as a Read Only class. ''' </summary> ''' <value>Boolean indicating the classes read only status</value> @@ -518,7 +497,7 @@ ''' A collection of standard association maps. ''' </summary> ''' <value>A collection of association maps</value> - ''' <remarks>Contains association maps that are not marked as Inverse.</remarks> + ''' <remarks>Contains association maps</remarks> ''' <history> ''' [rbanks] 27/11/2003 Created ''' </history> @@ -633,7 +612,6 @@ m_associationMaps = New HybridDictionary m_referenceAttributeMaps = New Collection m_Tables = New Collection - m_inverseAssociationMaps = New Collection m_straightAssociationMaps = New Collection m_findAttributeMaps = New Collection m_identityAttributeMaps = New Collection @@ -652,20 +630,14 @@ ''' Adds an association map to the class map ''' </summary> ''' <param name="map">The association map to add</param> - ''' <remarks>Adds the association map to the class. The Inverse flag of the - ''' map is checked and the association map is also added to either the Inverse or - ''' Straight association maps.</remarks> + ''' <remarks>Adds the association map to the class.</remarks> ''' <history> ''' [rbanks] 27/11/2003 Created ''' </history> '''----------------------------------------------------------------------------- Public Sub addAssociationMap(ByVal map As CUDAMap) m_associationMaps.Add(map.Name, map) - If map.Inverse Then - m_inverseAssociationMaps.Add(map) - Else - m_straightAssociationMaps.Add(map) - End If + m_straightAssociationMaps.Add(map) End Sub '''----------------------------------------------------------------------------- @@ -978,7 +950,7 @@ statement.addSqlClause(Me.RelationalDatabase.getClauseStringSelect) If rowLimit > 0 And Me.RelationalDatabase.limitClauseAtStart Then statement.addSqlClause(" " & Me.RelationalDatabase.getClauseStringLimit) - If rowOffset > 0 andalso Me.RelationalDatabase.supportsSelectOffsets Then + If rowOffset > 0 AndAlso Me.RelationalDatabase.supportsSelectOffsets Then statement.addSqlClause(" " & Str(rowOffset) & ",") End If statement.addSqlClause(" " & Str(rowLimit)) @@ -1669,7 +1641,7 @@ '''----------------------------------------------------------------------------- ''' <summary> - ''' Gets the number of non-inverse associations for the class maop + ''' Gets the number of associations for the class maop ''' </summary> ''' <returns>The number of standard associations</returns> ''' <remarks>None.</remarks> @@ -1683,20 +1655,6 @@ '''----------------------------------------------------------------------------- ''' <summary> - ''' Gets the number of inverse associations for the class maop - ''' </summary> - ''' <returns>The number of inverse associations</returns> - ''' <remarks>None.</remarks> - ''' <history> - ''' [rbanks] 27/11/2003 Created - ''' </history> - '''----------------------------------------------------------------------------- - Public Function getInverseAssociationMapSize() As Short - getInverseAssociationMapSize = m_inverseAssociationMaps.Count() - End Function - - '''----------------------------------------------------------------------------- - ''' <summary> ''' Gets a specific association map from the class map ''' </summary> ''' <param name="index">The index position of the association map.</param> @@ -1714,23 +1672,6 @@ '''----------------------------------------------------------------------------- ''' <summary> - ''' Gets a specific Inverse association map from the class map - ''' </summary> - ''' <param name="index">The index position of the association map.</param> - ''' <returns>The Inverse association map at the specified position</returns> - ''' <remarks>None.</remarks> - ''' <history> - ''' [rbanks] 27/11/2003 Created - ''' </history> - '''----------------------------------------------------------------------------- - Public Function getInverseAssociationMap(ByVal index As Short) As CUDAMap - Dim udaMap As CUDAMap - udaMap = Me.InverseAssociationMaps.Item(index) - getInverseAssociationMap = udaMap - End Function - - '''----------------------------------------------------------------------------- - ''' <summary> ''' Gets SQL text for processing inheritance associations. ''' </summary> ''' <returns>A string containing the SQL statement.</returns> @@ -1811,7 +1752,7 @@ For Each de In oneClassMap.AssociationMaps udamap = de.Value - If udamap.FromClass.Equals(oneClassMap) And udamap.ForClass.Equals(manyClassMap) And udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Then + If udamap.FromClass.Equals(oneClassMap) And udamap.ToClass.Equals(manyClassMap) And udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Then Return True End If Next @@ -1871,10 +1812,16 @@ If udamap.RetrieveAutomatic Then classMapCount += 1 mapName = "t" & classMapCount.ToString - rMaps.Add(mapName, udamap.ForClass) - m_joinSet = New CJoin(m_joinSet, udamap.ForClass, mapName, udamap) - 'Add joins for multiple inheritance - pbroker.createJoinForMultipleInheritance(udamap.ForClass, classMapCount, m_joinSet, rMaps) + If udamap.Cardinality = CUDAMap.CardinalityEnum.MANY_TO_MANY AndAlso Me.Name <> udamap.FromClass.Name Then + rMaps.Add(mapName, udamap.ToClass) + m_joinSet = New CJoin(m_joinSet, udamap.FromClass, mapName, udamap) + pbroker.createJoinForMultipleInheritance(udamap.FromClass, classMapCount, m_joinSet, rMaps) + Else + rMaps.Add(mapName, udamap.ToClass) + m_joinSet = New CJoin(m_joinSet, udamap.ToClass, mapName, udamap) + 'Add joins for multiple inheritance + pbroker.createJoinForMultipleInheritance(udamap.ToClass, classMapCount, m_joinSet, rMaps) + End If End If Next @@ -1994,10 +1941,10 @@ If udamap.RetrieveAutomatic Then classMapCount += 1 mapName = "t" & classMapCount.ToString - rMaps.Add(mapName, udamap.ForClass) - m_joinSet = New CJoin(m_joinSet, udamap.ForClass, mapName, udamap) + rMaps.Add(mapName, udamap.ToClass) + m_joinSet = New CJoin(m_joinSet, udamap.ToClass, mapName, udamap) 'Add joins for multiple inheritance - pbroker.createJoinForMultipleInheritance(udamap.ForClass, classMapCount, m_joinSet, rMaps) + pbroker.createJoinForMultipleInheritance(udamap.ToClass, classMapCount, m_joinSet, rMaps) End If Next Index: CMultiSummaryCriteria.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CMultiSummaryCriteria.vb,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- CMultiSummaryCriteria.vb 28 Oct 2004 00:16:12 -0000 1.12 +++ CMultiSummaryCriteria.vb 9 Feb 2005 06:24:44 -0000 1.13 @@ -265,7 +265,7 @@ For i = 0 To UBound(myArrayStrings) - 1 strName = myArrayStrings(i) udaMap = clMap.AssociationMaps(strName) - clMap = udaMap.ForClass + clMap = udaMap.toclass If clMap Is Nothing Then Exit For End If Index: XMLMapping.xsd =================================================================== RCS file: /cvsroot/jcframework/dotnet/XMLMapping.xsd,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- XMLMapping.xsd 7 Feb 2005 07:37:35 -0000 1.2 +++ XMLMapping.xsd 9 Feb 2005 06:24:45 -0000 1.3 @@ -63,11 +63,11 @@ <xs:attribute name="fromClass" form="unqualified" type="xs:string" use="required" /> <xs:attribute name="toClass" form="unqualified" type="xs:string" use="required" /> <xs:attribute name="cardinality" form="unqualified" type="cardinality" use="required" /> - <xs:attribute name="target" form="unqualified" type="xs:string" use="required" /> + <xs:attribute name="fromClassTarget" form="unqualified" type="xs:string" use="required" /> + <xs:attribute name="toClassTarget" form="unqualified" type="xs:string" /> <xs:attribute name="retrieveAutomatic" form="unqualified" type="TrueFalse" use="required" /> <xs:attribute name="deleteAutomatic" form="unqualified" type="TrueFalse" use="required" /> <xs:attribute name="saveAutomatic" form="unqualified" type="TrueFalse" use="required" /> - <xs:attribute name="inverse" form="unqualified" type="TrueFalse" /> <xs:attribute name="fromClassNameSpace" type="xs:string" /> <xs:attribute name="toClassNameSpace" type="xs:string" /> </xs:complexType> --- NEW FILE: CAssociationKey.vb --- Public Class CAssociationKey Private m_attributemap As CAttributeMap Private m_columnname As CColumnMap Public Property AttributeMap() As CAttributeMap Get Return m_attributemap End Get Set(ByVal Value As CAttributeMap) m_attributemap = Value End Set End Property Public Property ColumnMap() As CColumnMap Get Return m_columnname End Get Set(ByVal Value As CColumnMap) m_columnname = Value End Set End Property End Class Public Class CAssociationKeys Inherits CollectionBase Public Sub Add(ByVal key As CAssociationKey) list.Add(key) End Sub Default Public ReadOnly Property Item(ByVal index As Integer) As CAssociationKey Get Return CType(list.Item(index), CAssociationKey) End Get End Property End Class --- NEW FILE: CAssociationObject.vb --- 'private object used for saving table entries in many-to-many associations Friend Class CAssociationObject Private m_objA As IPersistableObject Private m_objB As IPersistableObject Private m_classMapA As CClassMap Private m_classMapB As CClassMap Private m_association As CUDAMap Private m_objACol As Collection Private m_objBCol As Collection Private m_deleteNeeded As Boolean Public Property ObjectA() As IPersistableObject Get Return m_objA End Get Set(ByVal Value As IPersistableObject) m_objA = Value If Not m_objB Is Nothing AndAlso Not m_objA Is Nothing Then checkifdeletewillbeneeded() End If End Set End Property Public Property ClassMapA() As CClassMap Get Return m_classMapA End Get Set(ByVal Value As CClassMap) m_classMapA = Value End Set End Property Public Property ObjectB() As IPersistableObject Get Return m_objB End Get Set(ByVal Value As IPersistableObject) m_objB = Value If Not m_objA Is Nothing AndAlso Not m_objB Is Nothing Then checkifdeletewillbeneeded() End If End Set End Property Public Property ClassMapB() As CClassMap Get Return m_classMapB End Get Set(ByVal Value As CClassMap) m_classMapB = Value End Set End Property Public Property Association() As CUDAMap Get Return m_association End Get Set(ByVal Value As CUDAMap) m_association = Value End Set End Property Public ReadOnly Property DeleteNeeded() As Boolean Get Return m_deleteNeeded End Get End Property Public Function getInsertSql() As CSqlStatement Dim isFirst As Boolean Dim db As _CRelationalDatabase Dim m_insertStatement As New CSqlStatement Dim paramCount As Integer Dim AttrMap As CAttributeMap Dim Key As CAssociationKey Dim fromObj, toObj As IPersistableObject Dim i As Short db = m_classMapA.RelationalDatabase 'Determine which order classes are in If m_classMapA.Name = m_association.FromClass.Name Then fromObj = m_objA toObj = m_objB Else fromObj = m_objB toObj = m_objA End If m_insertStatement.addSqlClause(db.getClauseStringInsert & " ") m_insertStatement.addSqlClause(m_association.AssocationTable.Name & " ") m_insertStatement.addSqlClause("(") isFirst = True For i = 0 To m_association.AssocationTable.FromKeys.Count - 1 Key = m_association.AssocationTable.FromKeys.Item(i) If isFirst Then m_insertStatement.addSqlClause(Key.ColumnMap.Name) isFirst = False Else m_insertStatement.addSqlClause(", " & Key.ColumnMap.Name) End If Next i For i = 0 To m_association.AssocationTable.ToKeys.Count - 1 Key = m_association.AssocationTable.ToKeys.Item(i) If isFirst Then m_insertStatement.addSqlClause(Key.ColumnMap.Name) isFirst = False Else m_insertStatement.addSqlClause(", " & Key.ColumnMap.Name) End If Next i m_insertStatement.addSqlClause(") ") m_insertStatement.addSqlClause(db.getClauseStringValues & " ") m_insertStatement.addSqlClause("(") isFirst = True For i = 1 To (m_association.AssocationTable.FromKeys.Count + m_association.AssocationTable.FromKeys.Count) If isFirst Then m_insertStatement.addSqlClause(db.getParamHolder(i)) isFirst = False Else m_insertStatement.addSqlClause(", " & db.getParamHolder(i)) End If Next i m_insertStatement.addSqlClause(")") 'Add parameter values paramCount = 1 For i = 0 To m_association.AssocationTable.FromKeys.Count - 1 Key = m_association.AssocationTable.FromKeys.Item(i) m_insertStatement.addSqlParameter(paramCount, fromObj.GetValueByAttribute(Key.AttributeMap.Name), Key.ColumnMap) paramCount += 1 Next i For i = 0 To m_association.AssocationTable.ToKeys.Count - 1 Key = m_association.AssocationTable.ToKeys.Item(i) m_insertStatement.addSqlParameter(paramCount, toObj.GetValueByAttribute(Key.AttributeMap.Name), Key.ColumnMap) paramCount += 1 Next i Return m_insertStatement End Function Public Function getDeleteSql() As CSqlStatement Dim isFirst As Boolean Dim db As _CRelationalDatabase Dim m_deleteStatement As New CSqlStatement Dim paramCount As Integer Dim AttrMap As CAttributeMap Dim Key As CAssociationKey Dim fromObj, toObj As IPersistableObject Dim i As Short db = m_classMapA.RelationalDatabase 'Determine which order classes are in If m_classMapA.Name = m_association.FromClass.Name Then fromObj = m_objA toObj = m_objB Else fromObj = m_objB toObj = m_objA End If m_deleteStatement.addSqlClause(db.getClauseStringDelete & " " & db.getClauseStringFrom & " ") m_deleteStatement.addSqlClause(m_association.AssocationTable.Name & " ") m_deleteStatement.addSqlClause(db.getClauseStringWhere & " ") paramCount = 1 For i = 0 To m_association.AssocationTable.FromKeys.Count - 1 Key = m_association.AssocationTable.FromKeys.Item(i) If i > 1 Then m_deleteStatement.addSqlClause(" " & db.getClauseStringAnd & " ") End If m_deleteStatement.addSqlClause(Key.ColumnMap.getFullyQualifiedName & db.getClauseStringEqualTo("_" & i.ToString & "_")) m_deleteStatement.addSqlParameter(paramCount, fromObj.GetValueByAttribute(Key.AttributeMap.Name), Key.ColumnMap) paramCount += 1 Next i For i = 0 To m_association.AssocationTable.ToKeys.Count - 1 Key = m_association.AssocationTable.ToKeys.Item(i) If i > 1 Then m_deleteStatement.addSqlClause(" " & db.getClauseStringAnd & " ") End If m_deleteStatement.addSqlClause(Key.ColumnMap.getFullyQualifiedName & db.getClauseStringEqualTo("_" & i.ToString & "_")) m_deleteStatement.addSqlParameter(paramCount, fromObj.GetValueByAttribute(Key.AttributeMap.Name), Key.ColumnMap) paramCount += 1 Next i Dim x As String = m_deleteStatement.SqlString Dim p As CSQLParameter For i = 1 To paramCount p = m_deleteStatement.Parameters.Item(i) If IsNullAlias(p.Value) Then If db.UseANSINulls = True Then x = x.Replace(" = _" & i.ToString & "_", " is NULL") p.Ignore = True Else x = x.Replace("_" & i.ToString & "_", db.getParamHolder(i)) End If Else x = x.Replace("_" & i.ToString & "_", db.getParamHolder(i)) End If Next m_deleteStatement.SqlString = x Return m_deleteStatement End Function Public Function getDeleteSqlUsingOriginalValues() As CSqlStatement Dim isFirst As Boolean Dim db As _CRelationalDatabase Dim m_deleteStatement As New CSqlStatement Dim paramCount As Integer Dim AttrMap As CAttributeMap Dim Key As CAssociationKey Dim fromObj, toObj As IPersistableObject Dim fromCol, toCol As Collection Dim i As Short db = m_classMapA.RelationalDatabase 'Determine which order classes are in If m_classMapA.Name = m_association.FromClass.Name Then fromObj = m_objA toObj = m_objB fromCol = m_objACol toCol = m_objBCol Else fromObj = m_objB toObj = m_objA toCol = m_objACol fromCol = m_objBCol End If m_deleteStatement.addSqlClause(db.getClauseStringDelete & " " & db.getClauseStringFrom & " ") m_deleteStatement.addSqlClause(m_association.AssocationTable.Name & " ") m_deleteStatement.addSqlClause(db.getClauseStringWhere & " ") paramCount = 1 For i = 0 To m_association.AssocationTable.FromKeys.Count - 1 Key = m_association.AssocationTable.FromKeys.Item(i) If i > 1 Then m_deleteStatement.addSqlClause(" " & db.getClauseStringAnd & " ") End If m_deleteStatement.addSqlClause(Key.ColumnMap.getFullyQualifiedName & db.getClauseStringEqualTo("_" & i.ToString & "_")) m_deleteStatement.addSqlParameter(paramCount, fromCol.Item(i), Key.ColumnMap) paramCount += 1 Next i For i = 0 To m_association.AssocationTable.ToKeys.Count - 1 Key = m_association.AssocationTable.ToKeys.Item(i) If i > 1 Then m_deleteStatement.addSqlClause(" " & db.getClauseStringAnd & " ") End If m_deleteStatement.addSqlClause(Key.ColumnMap.getFullyQualifiedName & db.getClauseStringEqualTo("_" & i.ToString & "_")) m_deleteStatement.addSqlParameter(paramCount, toCol.Item(i), Key.ColumnMap) paramCount += 1 Next i Dim x As String = m_deleteStatement.SqlString Dim p As CSQLParameter For i = 1 To paramCount p = m_deleteStatement.Parameters.Item(i) If IsNullAlias(p.Value) Then If db.UseANSINulls = True Then x = x.Replace(" = _" & i.ToString & "_", " is NULL") p.Ignore = True Else x = x.Replace("_" & i.ToString & "_", db.getParamHolder(i)) End If Else x = x.Replace("_" & i.ToString & "_", db.getParamHolder(i)) End If Next m_deleteStatement.SqlString = x Return m_deleteStatement End Function Private Sub CheckIfDeleteWillBeNeeded() Dim i As Integer Dim attrMap As CAttributeMap Dim Value, Value2 As Object m_deleteNeeded = False If Not m_objA.OriginalCacheKey Is Nothing AndAlso Not m_objB.OriginalCacheKey Is Nothing Then 'Copy values while looking for changes For i = 1 To m_objA.GetClassMap.getKeySize attrMap = m_objA.GetClassMap.getKeyAttributeMap(i) Value = m_objA.OriginalCacheKey.GetKeyValue(i) Value2 = m_objA.GetValueByAttribute(attrMap.Name) m_objACol.Add(Value) Try If Not Value Is Nothing AndAlso Not Value2 Is Nothing Then If Not Value.Equals(Value2) Then m_deleteNeeded = True End If End If Catch ex As Exception End Try Next For i = 1 To m_objB.GetClassMap.getKeySize attrMap = m_objB.GetClassMap.getKeyAttributeMap(i) Value = m_objB.OriginalCacheKey.GetKeyValue(i) Value2 = m_objB.GetValueByAttribute(attrMap.Name) m_objBCol.Add(Value) Try If Not Value Is Nothing AndAlso Not Value2 Is Nothing Then If Not Value.Equals(Value2) Then m_deleteNeeded = True End If End If Catch ex As Exception End Try Next End If End Sub End Class Index: CCriteriaCondition.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CCriteriaCondition.vb,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- CCriteriaCondition.vb 28 Oct 2004 00:16:12 -0000 1.16 +++ CCriteriaCondition.vb 9 Feb 2005 06:24:44 -0000 1.17 @@ -333,7 +333,7 @@ udaMap = clMap.AssociationMaps(strName) m_Associations.Add(udaMap) - clMap =... [truncated message content] |