private static void ValidateConceptTypeChildNameChanged(ConceptTypeChild child) { if (null != child) { FrameworkDomainModel.DelayValidateElement(child, DelayValidateConceptTypeChildNameChanged); } }
private static void ValidateMandatoryDelayed(ModelElement element) { if (!element.IsDeleted) { ConceptTypeChild child = (ConceptTypeChild)element; bool newMandatory = true; foreach (FactType factType in ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(child)) { FactTypeMapsTowardsRole towardsRoleLink = FactTypeMapsTowardsRole.GetLinkToTowardsRole(factType); if (null == towardsRoleLink) { newMandatory = false; break; } else { switch (towardsRoleLink.MandatoryPattern) { case MappingMandatoryPattern.None: case MappingMandatoryPattern.NotMandatory: case MappingMandatoryPattern.OppositeRoleMandatory: newMandatory = false; break; } if (!newMandatory) { break; } } } child.IsMandatory = newMandatory; } }
private static void ValidateAssociatedColumnsIsNullable(ConceptTypeChild child) { bool canBeNullable = !child.IsMandatory; foreach (Column column in ColumnHasConceptTypeChild.GetColumn(child)) { FrameworkDomainModel.DelayValidateElement(column, ValidateColumnIsNullableDelayed); } }
private static void DelayValidateConceptTypeChildNameChanged(ModelElement element) { if (!element.IsDeleted) { ConceptTypeChild child = (ConceptTypeChild)element; foreach (Column column in ColumnHasConceptTypeChild.GetColumn(child)) { ValidateSchemaNamesChanged(column.Table.Schema); } } }
/// <summary> /// DeleteRule: typeof(ConceptTypeChildHasPathFactType) /// </summary> private static void ConceptTypeChildPathBridgeDetachedRule(ElementDeletedEventArgs e) { ConceptTypeChild child = ((ConceptTypeChildHasPathFactType)e.ModelElement).ConceptTypeChild; ConceptType conceptType = child.Parent; if (conceptType != null && !conceptType.IsDeleted && TestRebuildAbstractionModel(conceptType.Model)) { AddTransactedModelElement(conceptType, ModelElementModification.AbstractionElementDetached); } }
/// <summary> /// The <see cref="ConceptTypeChild.IsMandatory">IsMandatory</see> setting may /// have change, revalidate if necessary. /// </summary> /// <param name="child">The <see cref="ConceptTypeChild"/> element to validate</param> /// <param name="oldMandatory">The old mandatory pattern for any <see cref="FactType"/> in the path.</param> /// <param name="newMandatory">The new mandatory pattern for any <see cref="FactType"/> in the path.</param> private static void ValidateMandatory(ConceptTypeChild child, MappingMandatoryPattern oldMandatory, MappingMandatoryPattern newMandatory) { // We pre filter this and don't both to notify unless a change is possible bool mightHaveChanged = false; if (child.IsMandatory) { switch (oldMandatory) { case MappingMandatoryPattern.BothRolesMandatory: case MappingMandatoryPattern.TowardsRoleMandatory: switch (newMandatory) { case MappingMandatoryPattern.OppositeRoleMandatory: case MappingMandatoryPattern.NotMandatory: mightHaveChanged = true; break; } break; } } else { switch (oldMandatory) { case MappingMandatoryPattern.NotMandatory: case MappingMandatoryPattern.OppositeRoleMandatory: switch (newMandatory) { case MappingMandatoryPattern.BothRolesMandatory: case MappingMandatoryPattern.TowardsRoleMandatory: mightHaveChanged = true; break; } break; } } if (mightHaveChanged) { FrameworkDomainModel.DelayValidateElement(child, ValidateMandatoryDelayed); } }
private static bool IsSimpleManyToManyAssociation(ConceptType conceptType) { LinkedElementCollection <ConceptTypeChild> associationChildren = ConceptTypeHasChildAsPartOfAssociation.GetTargetCollection(conceptType); ConceptTypeChild child0; ConceptTypeChild child1; if (associationChildren.Count == 2 && !((child0 = associationChildren[0]) is InformationType) && !((child1 = associationChildren[1]) is InformationType)) { ReadOnlyCollection <ConceptTypeChild> allChildren = ConceptTypeChild.GetLinksToTargetCollection(conceptType); if (allChildren.Count == 2) { return (child0 == allChildren[0] && child1 == allChildren[1] || child0 == allChildren[1] && child1 == allChildren[0]); } } return(false); }
/// <summary> /// Get a minimal unique identifier for a column based on mapped roles. The identifer /// will stop as soon as the fact type is used in a single column or in a partitioned /// or separated column. /// </summary> /// <param name="column">The <see cref="Column"/> to analyze</param> /// <param name="idList">Scratch list used to determine keys</param> /// <param name="minKeySize">The minimum number of ids that uniquely /// identify this column. The actually key may be longer than this /// minimimum for partitioned and separated tables. Key comparisons /// may be performed down to this minimum size.</param> /// <returns><see langword="true"/> if the key was available.</returns> private static bool BuildKey(Column column, List <Guid> idList, out int minKeySize) { idList.Clear(); int uniqueUseIndex = -1; minKeySize = 0; LinkedElementCollection <ConceptTypeChild> childNodes = ColumnHasConceptTypeChild.GetConceptTypeChildPath(column); for (int i = childNodes.Count - 1; i >= 0; --i) { ConceptTypeChild child = childNodes[i]; bool uniqueChild = ColumnHasConceptTypeChild.GetLinksToColumn(child).Count == 1; LinkedElementCollection <FactType> pathFactTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(child); int factTypeCount = pathFactTypes.Count; InformationType infoType; ObjectType objectType; if (0 != (factTypeCount = pathFactTypes.Count)) { for (int j = factTypeCount - 1; j >= 0; --j) { FactType factType = pathFactTypes[j]; idList.Add(FactTypeMapsTowardsRole.GetTowardsRole(factType).Id); if (-1 == uniqueUseIndex && uniqueChild && ConceptTypeChildHasPathFactType.GetLinksToConceptTypeChild(factType).Count == 1) { minKeySize = idList.Count; uniqueUseIndex = minKeySize - 1; } } ConceptTypeAssimilatesConceptType assimilation; if (uniqueUseIndex != -1 && null != (assimilation = child as ConceptTypeAssimilatesConceptType) && AssimilationMapping.GetAbsorptionChoiceFromAssimilation(assimilation) != AssimilationAbsorptionChoice.Absorb) { uniqueUseIndex = idList.Count - 1; } } else if (null != (infoType = child as InformationType) && null != (objectType = ConceptTypeIsForObjectType.GetObjectType(infoType.ConceptType))) { // Happens for a value column in an object type table, which has one concept type child idList.Add(objectType.Id); } } int count = idList.Count; if (0 == count) { return(false); } if (uniqueUseIndex != -1 && (uniqueUseIndex + 1) < count) { idList.RemoveRange(uniqueUseIndex + 1, count - uniqueUseIndex - 1); } if (minKeySize == 0) { minKeySize = idList.Count; } return(true); }
/// <summary> /// for regular relationships /// </summary> /// <param name="relation"></param> /// <param name="source"></param> /// <param name="target"></param> /// <param name="notifyAdded"></param> /// <param name="associationCounter"></param> /// <returns></returns> private static bool CreateBinaryAssociation(ConceptTypeChild relation, ConceptType source, ConceptType target, INotifyElementAdded notifyAdded, ref int associationCounter) { if (BinaryAssociationHasConceptTypeChild.GetBinaryAssociation(relation).Count > 0) { //it has already been created return(true); } else if (EntityTypeIsPrimarilyForConceptType.GetEntityType(target) != null) { #region create association BinaryAssociation b = new BinaryAssociation(relation.Store, new PropertyAssignment[] { new PropertyAssignment(BinaryAssociation.NumberDomainPropertyId, associationCounter++) }); //new BinaryAssociationHasConceptTypeChild(b, relation); BinaryAssociationHasConceptTypeChild.GetConceptTypeChildPath(b).Add(relation); Role r1 = new Role(relation.Store, new PropertyAssignment[] { new PropertyAssignment(Role.PredicateTextDomainPropertyId, source.Name) }); Role r2 = new Role(relation.Store, new PropertyAssignment[] { new PropertyAssignment(Role.PredicateTextDomainPropertyId, target.Name) }); b.RoleCollection.Add(r1); b.RoleCollection.Add(r2); EntityType sourceEntity = EntityTypeIsPrimarilyForConceptType.GetEntityType(source); EntityType targetEntity = EntityTypeIsPrimarilyForConceptType.GetEntityType(target); sourceEntity.RoleCollection.Add(r1); targetEntity.RoleCollection.Add(r2); sourceEntity.BarkerErModel.BinaryAssociationCollection.Add(b); #endregion //determine whether roles are mandatory or optional List <ConceptTypeChild> links = new List <ConceptTypeChild>(1); links.Add(relation); r1.IsMandatory = AllStepsMandatory(targetEntity, links); if (relation is ConceptTypeAssimilatesConceptType) { r2.IsMandatory = AllStepsMandatory(sourceEntity, links); } #region determine whether roles are multivalued or not - and possibly rename ORMCore.ObjectType sourceObjectType = ConceptTypeIsForObjectType.GetObjectType(source); ORMCore.ObjectType targetObjectType = ConceptTypeIsForObjectType.GetObjectType(target); ORMCore.UniquenessConstraint uSource = null, uTarget = null; foreach (ORMCore.FactType factType in ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(relation)) { Debug.Assert(factType.RoleCollection.Count == 2, "Error when mapping to Barker ER; the fact type is not binary"); foreach (ORMCore.RoleBase r in factType.RoleCollection) { //need to use RoleBase because we might run into RoleProxy ORMCore.Role role = r.Role; foreach (ORMCore.ConstraintRoleSequence constraintRoleSequence in role.ConstraintRoleSequenceCollection) { ORMCore.UniquenessConstraint uninquenessConstraint = constraintRoleSequence as ORMCore.UniquenessConstraint; if (uninquenessConstraint != null && //check that it's a uniqueness constraint uninquenessConstraint.Modality == ORMCore.ConstraintModality.Alethic && //check it's alethic uninquenessConstraint.IsInternal) //check it's internal { if (role.RolePlayer == sourceObjectType) { uSource = uninquenessConstraint; } if (role.RolePlayer == targetObjectType) { uTarget = uninquenessConstraint; } } } } //name the roles properly //TODO this is a hack; proper name generation is yet to be implemented foreach (ORMCore.ReadingOrder order in factType.ReadingOrderCollection) { string text = order.ReadingText; int first = text.IndexOf('}') + 1; text = text.Substring(first, text.LastIndexOf('{') - first); text = text.Trim(); if (!string.IsNullOrEmpty(text) && order.RoleCollection != null && order.RoleCollection.Count > 0 && order.RoleCollection[0].Role != null) { ORMCore.ObjectType o = order.RoleCollection[0].Role.RolePlayer; if (o == sourceObjectType) { r1.PredicateText = text; } else if (o == targetObjectType) { r2.PredicateText = text; } } } } if (uSource != null && uSource == uTarget) { //it's many-to-many r1.IsMultiValued = true; r2.IsMultiValued = true; } else if (uSource == null || uTarget == null) { //it's one-to-many r1.IsMultiValued = uSource != null; r2.IsMultiValued = uTarget != null; } else if (uSource != null && uTarget != null) { //it's one-to-one r1.IsMultiValued = false; r2.IsMultiValued = false; } else { Debug.Fail("Found a fact type with no uniqueness constraints!"); } #endregion #region primary id? foreach (Uniqueness u in UniquenessIncludesConceptTypeChild.GetUniquenessCollection(relation)) { if (u.IsPreferred) { r1.IsPrimaryIdComponent = true; break; } } #endregion //notify elements added if (notifyAdded != null) { notifyAdded.ElementAdded(b, true); notifyAdded.ElementAdded(r1, true); notifyAdded.ElementAdded(r2, true); } return(true); } else { //should not create binary association in this case return(false); } }