/// <summary> /// DeletingRule: typeof(UniquenessConstraintIncludesColumn) /// If a uniqueness constraint column is being removed, then remove the corresponding column /// in any reference constraints that target the columns in the uniqueness constraint. /// </summary> private static void UniquenessConstraintColumnDeleting(ElementDeletingEventArgs e) { UniquenessConstraintIncludesColumn link = (UniquenessConstraintIncludesColumn)e.ModelElement; UniquenessConstraint uniquenessConstraint = link.UniquenessConstraint; if (!uniquenessConstraint.IsDeleting) { bool haveIndex = false; int index = -1; foreach (ReferenceConstraint referenceConstraint in uniquenessConstraint.ReferenceConstraintCollection) { if (!haveIndex) { haveIndex = true; index = UniquenessConstraintIncludesColumn.GetLinksToColumnCollection(uniquenessConstraint).IndexOf(link); } LinkedElementCollection <ColumnReference> columnRefs = referenceConstraint.ColumnReferenceCollection; if (index < columnRefs.Count && columnRefs[index].TargetColumn == link.Column) // Sanity check { columnRefs.RemoveAt(index); } else { // Something is off, delay validate this later ReferenceConstraintTargetsTable tableLink = ReferenceConstraintTargetsTable.GetLinkToTargetTable(referenceConstraint); if (tableLink != null) { FrameworkDomainModel.DelayValidateElement(tableLink, DelayValidateTargetUniquenessConstraint); } } } } }
/// <summary> /// AddRule: typeof(UniquenessConstraintIncludesColumn) /// Verify any related <see cref="ReferenceConstraint"/> when a new /// column is added to a uniqueness constraint. The reference constraint /// needs to be deleted if the calling code has not made a matching modification /// by the end of the transaction. /// </summary> private static void UniquenessConstraintColumnAdded(ElementAddedEventArgs e) { foreach (ReferenceConstraint referenceConstraint in ReferenceConstraintTargetsUniquenessConstraint.GetReferenceConstraintCollection(((UniquenessConstraintIncludesColumn)e.ModelElement).UniquenessConstraint)) { ReferenceConstraintTargetsTable tableLink = ReferenceConstraintTargetsTable.GetLinkToTargetTable(referenceConstraint); if (tableLink != null) { FrameworkDomainModel.DelayValidateElement(tableLink, DelayValidateTargetUniquenessConstraint); } } }
/// <summary> /// AddRule: typeof(ORMSolutions.ORMArchitect.RelationalModels.ConceptualDatabase.ReferenceConstraintTargetsTable), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.AddConnectionRulePriority; /// Add a <see cref="ForeignKeyConnector"/> to the diagram /// </summary> private static void ReferenceConstraintAddedRule(ElementAddedEventArgs e) { ReferenceConstraintTargetsTable link = (ReferenceConstraintTargetsTable)e.ModelElement; Table sourceTable; Schema schema; Catalog catalog; if (null != (sourceTable = link.ReferenceConstraint.SourceTable) && null != (schema = sourceTable.Schema) && null != (catalog = schema.Catalog)) { FixUpDiagram(catalog, link); } }
/// <summary> /// Correctly connect a <see cref="ForeignKeyConnector"/> /// </summary> protected override void OnChildConfiguring(ShapeElement child, bool createdDuringViewFixup) { ForeignKeyConnector foreignKeyConnector; if (null != (foreignKeyConnector = child as ForeignKeyConnector)) { ReferenceConstraintTargetsTable link = (ReferenceConstraintTargetsTable)child.ModelElement; TableShape sourceShape = null; Table sourceTable; if (null != (sourceTable = link.ReferenceConstraint.SourceTable)) { foreach (PresentationElement pel in PresentationViewsSubject.GetPresentation(sourceTable)) { TableShape testShape = pel as TableShape; if (testShape != null && testShape.Diagram == this) { sourceShape = testShape; break; } } } if (null != sourceShape) { foreach (PresentationElement pel in PresentationViewsSubject.GetPresentation(link.TargetTable)) { TableShape targetShape = pel as TableShape; if (targetShape != null && targetShape.Diagram == this) { foreignKeyConnector.Connect(sourceShape, targetShape); return; } } } } base.OnChildConfiguring(child, createdDuringViewFixup); }
private static void ValidateTargetUniquenessConstraint(ReferenceConstraintTargetsTable tableReference, INotifyElementAdded notifyAdded) { if (tableReference.IsDeleted) { return; } Table targetTable = tableReference.TargetTable; ReferenceConstraint referenceConstraint = tableReference.ReferenceConstraint; LinkedElementCollection <ColumnReference> columnRefs = referenceConstraint.ColumnReferenceCollection; int columnRefCount = columnRefs.Count; ReferenceConstraintTargetsUniquenessConstraint targetUniquenessLink = ReferenceConstraintTargetsUniquenessConstraint.GetLinkToTargetUniquenessConstraint(referenceConstraint); if (targetUniquenessLink != null) { // Verify the target uniqueness UniquenessConstraint targetUniqueness = targetUniquenessLink.TargetUniquenessConstraint; bool existingIsValid = targetUniqueness.Table == targetTable; if (existingIsValid) { LinkedElementCollection <Column> uniquenessColumns = targetUniqueness.ColumnCollection; existingIsValid = uniquenessColumns.Count == columnRefCount; if (existingIsValid) { for (int i = 0; i < columnRefCount; ++i) { if (uniquenessColumns[i] != columnRefs[i].TargetColumn) { existingIsValid = false; break; } } } } if (!existingIsValid) { // Delete the link without deleting the reference constraint we're processing targetUniquenessLink.Delete(ReferenceConstraintTargetsUniquenessConstraint.ReferenceConstraintDomainRoleId); targetUniquenessLink = null; } } if (targetUniquenessLink == null) { foreach (UniquenessConstraint testUniqueness in targetTable.UniquenessConstraintCollection) { LinkedElementCollection <Column> uniquenessColumns = testUniqueness.ColumnCollection; if (uniquenessColumns.Count == columnRefCount) { int i = 0; for (; i < columnRefCount; ++i) { if (uniquenessColumns[i] != columnRefs[i].TargetColumn) { break; } } if (i == columnRefCount) { // We have a match targetUniquenessLink = new ReferenceConstraintTargetsUniquenessConstraint(referenceConstraint, testUniqueness); if (notifyAdded != null) { notifyAdded.ElementAdded(targetUniquenessLink, false); } break; } } } if (targetUniquenessLink == null) { referenceConstraint.Delete(); } } }
/// <summary> /// RolePlayerPositionChangeRule: typeof(UniquenessConstraintIncludesColumn) /// If a uniqueness constraint column is being repositioned, then reposition the corresponding column /// in any reference constraints that target the columns in the uniqueness constraint. /// </summary> private static void UniquenessConstraintColumnPositionChanged(RolePlayerOrderChangedEventArgs e) { if (e.CounterpartDomainRole.Id == UniquenessConstraintIncludesColumn.ColumnDomainRoleId) { UniquenessConstraint uniquenessConstraint = (UniquenessConstraint)e.SourceElement; int oldIndex = e.OldOrdinal; int newIndex = e.NewOrdinal; foreach (ReferenceConstraint referenceConstraint in uniquenessConstraint.ReferenceConstraintCollection) { LinkedElementCollection <ColumnReference> columnRefs = referenceConstraint.ColumnReferenceCollection; int columnRefCount = columnRefs.Count; if (newIndex < columnRefCount && oldIndex < columnRefCount && columnRefs[oldIndex].TargetColumn == e.CounterpartRolePlayer) // Sanity check { Column sourceColumn = columnRefs[oldIndex].SourceColumn; columnRefs.Move(oldIndex, newIndex); // Any uniqueness constraint that includes all columns in the // reference constraint will generate in a different order and // should be updated Table sourceTable; if (null != (sourceTable = referenceConstraint.SourceTable)) { foreach (UniquenessConstraint sourceUniquenessConstraint in sourceTable.UniquenessConstraintCollection) { LinkedElementCollection <Column> uniquenessColumns = sourceUniquenessConstraint.ColumnCollection; int uniquenessColumnCount = uniquenessColumns.Count; if (uniquenessColumnCount >= columnRefCount) { int firstMatchColumn = int.MaxValue; for (int i = 0; i < columnRefCount; ++i) { Column matchColumn = columnRefs[i].SourceColumn; int j = 0; for (; j < uniquenessColumnCount; ++j) { if (uniquenessColumns[j] == matchColumn) { firstMatchColumn = Math.Min(firstMatchColumn, j); break; } } if (j == uniquenessColumnCount) { // Not included firstMatchColumn = int.MaxValue; break; } } if (firstMatchColumn != int.MaxValue) { uniquenessColumnCount -= firstMatchColumn; if (newIndex < uniquenessColumnCount && oldIndex < uniquenessColumnCount && uniquenessColumns[firstMatchColumn + oldIndex] == sourceColumn) // Sanity check { uniquenessColumns.Move(firstMatchColumn + oldIndex, firstMatchColumn + newIndex); } // If this does not line up then something is clearly off, but // this is a non-critical error in that the model is still correctly // aligned and generates correct DDL. // However, the constraint will now have a different column order // than with a full regeneration. // UNDONE: Delay validation routine for this situation } } } } } else { // Something is off, delay validate this later ReferenceConstraintTargetsTable tableLink = ReferenceConstraintTargetsTable.GetLinkToTargetTable(referenceConstraint); if (tableLink != null) { FrameworkDomainModel.DelayValidateElement(tableLink, DelayValidateTargetUniquenessConstraint); } } } } }