/// <summary> /// Updates child action's status to the data store. /// </summary> /// <param name="action"></param> protected override void UpdateChildAction(MigrationAction action) { using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance()) { var changeActionQuery = context.RTChangeActionSet.Where (ca => ca.ChangeActionId == action.ActionId); int changeActionQueryCount = changeActionQuery.Count(); if (changeActionQueryCount == 0) { return; } Debug.Assert(changeActionQueryCount == 1); RTChangeAction rtChangeAction = changeActionQuery.First(); bool needToUpdateRTChangeAction = false; if (action.State == ActionState.Skipped) { rtChangeAction.IsSubstituted = true; needToUpdateRTChangeAction = true; } if (rtChangeAction.ActionId != action.Action) { rtChangeAction.ActionId = action.Action; needToUpdateRTChangeAction = true; } if (needToUpdateRTChangeAction) { context.TrySaveChanges(); } } }
public override IMigrationAction LoadSingleAction(long actionInternalId) { IMigrationAction retAction = null; using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance()) { Guid sessionUniqueId = new Guid(Session.SessionUniqueId); var actions = (from ca in context.RTChangeActionSet where ca.ChangeActionId == actionInternalId select ca); if (actions.Count() > 0) { RTChangeAction rtChangeAction = actions.First(); rtChangeAction.ChangeGroupReference.Load(); RTChangeGroup parentRTGroup = rtChangeAction.ChangeGroup; SqlChangeGroup parentChangeGroup = new SqlChangeGroup(this); retAction = parentChangeGroup.RealizeFromEDMWithSingleAction(parentRTGroup, rtChangeAction); } } return(retAction); }
private bool TryIgnoreNonFieldConflict(MigrationConflict conflict) { long targetChangeActionId; bool retVal = WITEditEditConflictType.TryGetConflictedTargetChangeActionId(conflict.ConflictDetails, out targetChangeActionId); if (!retVal) { // backward compatibility: // old-style edit/edit conflict details does not include target change action id // in that case, we can't find a change action to complete the anlaysis return(false); } using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance()) { // find the target-side change action (should be a delta table entry) var targetChangeActionQuery = context.RTChangeActionSet.Where(a => a.ChangeActionId == targetChangeActionId); if (targetChangeActionQuery.Count() != 1) { return(false); } RTChangeAction targetChangeAction = targetChangeActionQuery.First(); XmlDocument targetSideChanges = new XmlDocument(); targetSideChanges.LoadXml(targetChangeAction.ActionData); // if there are edits on the same field, we *cannot* ignore the conflict return(!(EditOnSameField(conflict.ConflictedChangeAction.MigrationActionDescription, targetSideChanges))); } }
private IMigrationAction RealizeSingleActionFromEDM( RTChangeAction runTimeChangeAction) { XmlDocument changeActionData = null; if (!string.IsNullOrEmpty(runTimeChangeAction.ActionData)) { changeActionData = new XmlDocument(); changeActionData.LoadXml(runTimeChangeAction.ActionData); } IMigrationItemSerializer itemSerializer = ManagerWithMigrationItemSerializers[runTimeChangeAction.ActionId]; DemandUnlocked("Cannot Create an action on a group after the initial Create"); SqlMigrationAction migrationAction = new SqlMigrationAction( this, runTimeChangeAction.ChangeActionId, runTimeChangeAction.ActionId, itemSerializer.LoadItem(runTimeChangeAction.SourceItem, Manager), runTimeChangeAction.FromPath, runTimeChangeAction.ToPath, runTimeChangeAction.Version, runTimeChangeAction.MergeVersionTo, runTimeChangeAction.ItemTypeReferenceName, changeActionData, runTimeChangeAction.IsSubstituted ? ActionState.Skipped : ActionState.Pending); if (!m_usePagedActions) { AddAction(migrationAction); } migrationAction.IsDirty = false; return(migrationAction); }
/// <summary> /// Realize a SqlMigrationAction from DB RTChangeAction. /// Note properties ChangeGroup, SourceItem and ActionData are not populated. /// </summary> /// <param name="RTChangeAction"></param> /// <returns></returns> internal static SqlMigrationAction RealizeFromDB(RTChangeAction RTChangeAction) { SqlMigrationAction migrationAction = new SqlMigrationAction(null, RTChangeAction.ChangeActionId, RTChangeAction.ActionId, null, RTChangeAction.FromPath, RTChangeAction.ToPath, RTChangeAction.Version, RTChangeAction.MergeVersionTo, RTChangeAction.ItemTypeReferenceName, null); return(migrationAction); }
private ConflictResolutionResult ResolveByUpdateConversionHisotry(MigrationConflict conflict, ConflictResolutionRule rule, out List <MigrationAction> actions) { actions = null; var unresolvedRslt = new ConflictResolutionResult(false, ConflictResolutionType.Other); string tgtItemId = rule.DataFieldDictionary[HistoryNotFoundUpdateConversionHistoryAction.DATAKEY_TARGET_ITEM_ID]; string srcRevRanges = rule.DataFieldDictionary[HistoryNotFoundUpdateConversionHistoryAction.DATAKEY_SOURCE_REVISION_RANGES]; string tgtRevRanges = rule.DataFieldDictionary[HistoryNotFoundUpdateConversionHistoryAction.DATAKEY_TARGET_REVISION_RANGES]; int[] srcRevs; int[] tgtRevs; if (string.IsNullOrEmpty(tgtItemId) || !IntegerRange.TryParseRangeString(srcRevRanges, out srcRevs) || !IntegerRange.TryParseRangeString(srcRevRanges, out tgtRevs) || srcRevs == null || srcRevs.Length == 0 || tgtRevs == null || tgtRevs.Length == 0 || srcRevs.Length != tgtRevs.Length) { return(unresolvedRslt); } WorkItemHistoryNotFoundConflictType conflictType = conflict.ConflictType as WorkItemHistoryNotFoundConflictType; Debug.Assert(null != conflictType, "conflictType is null"); WorkItemHistoryNotFoundConflictTypeDetails dtls = conflictType.GetConflictDetails(conflict); ConversionResult convRslt = new ConversionResult(dtls.SourceMigrationSourceId, dtls.TargetMigrationSourceId); convRslt.ChangeId = HistoryNotFoundResolutionChangeId; convRslt.ContinueProcessing = true; for (int i = 0; i < srcRevs.Length; ++i) { convRslt.ItemConversionHistory.Add(new ItemConversionHistory(dtls.SourceWorkItemID, srcRevs[i].ToString(), tgtItemId, tgtRevs[i].ToString())); } int sessionRunId = 0; Guid sourceMigrationSourceId = Guid.Empty; using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance()) { long actionInternalId = conflict.ConflictedChangeAction.ActionId; var actionQuery = context.RTChangeActionSet.Where(a => a.ChangeActionId == actionInternalId); if (actionQuery.Count() == 0) { return(unresolvedRslt); } RTChangeAction action = actionQuery.First(); action.ChangeGroupReference.Load(); action.ChangeGroup.SessionRunReference.Load(); sessionRunId = action.ChangeGroup.SessionRun.Id; sourceMigrationSourceId = action.ChangeGroup.SourceUniqueId; } convRslt.Save(sessionRunId, sourceMigrationSourceId); return(new ConflictResolutionResult(true, ConflictResolutionType.Other)); }
private void SkipChangeWithZeroFieldUpdates(RTChangeAction action) { XmlDocument doc = new XmlDocument(); doc.LoadXml(action.ActionData); if (!ChangeContainsFieldUpdates(doc)) { action.ChangeGroupReference.Load(); action.ChangeGroup.Status = (int)ChangeStatus.Skipped; } }
private bool TakeSource(MigrationConflict conflict) { // find the target-side change action (should be a delta table entry) // SIDE NOTE: // upon detection of a wit edit/edit conflict, we create // 1. an edit/edit conflict for the source side change group/action // 2. a chainonconflictconflict for the target side's (using the source-side conflict id as the scopehint) // look up for target-side conflicted change action id long targetChangeActionId; bool retVal = WITEditEditConflictType.TryGetConflictedTargetChangeActionId(conflict.ConflictDetails, out targetChangeActionId); if (!retVal) { // backward compatibility: // old-style edit/edit conflict details does not include target change action id // in that case, we can't find a change action to complete the anlaysis return(false); } using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance()) { Debug.Assert(conflict.ConflictedChangeAction != null, "Edit/Edit conflict ConflictedCangeAction is NULL"); // Extract all fields updated in the target change action string[] sourceSideChangedFields = ExtractFieldRefNames(conflict.ConflictedChangeAction.MigrationActionDescription); // find the target-side change action (should be a delta table entry) var changeActionQuery = context.RTChangeActionSet.Where(a => a.ChangeActionId == targetChangeActionId); if (changeActionQuery.Count() != 1) { return(false); } RTChangeAction targetChangeAction = changeActionQuery.First(); // drop the source-side updated fields from the target-side change // example: // source side change includes Field1, Field2, Field3 // target side change includes Field1, Field2, Field5, Field 6 // By taking source, we want to migrate Field1, Field2, Field3 to target side // Then migrate Field5, Field 6 to source side, i.e. dropping Field1, Field2 XmlDocument targetSideChanges = new XmlDocument(); targetSideChanges.LoadXml(targetChangeAction.ActionData); DropFields(targetSideChanges, sourceSideChangedFields); // update result for target change targetChangeAction.ActionData = targetSideChanges.OuterXml; SkipChangeWithZeroFieldUpdates(targetChangeAction); context.TrySaveChanges(); return(true); } }
private bool TakeTarget(MigrationConflict conflict) { // look up for target-side conflicted change action id long targetChangeActionId; bool retVal = WITEditEditConflictType.TryGetConflictedTargetChangeActionId(conflict.ConflictDetails, out targetChangeActionId); if (!retVal) { // backward compatibility: // old-style edit/edit conflict details does not include target change action id // in that case, we can't find a change action to complete the anlaysis return(false); } using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance()) { Debug.Assert(conflict.ConflictedChangeAction != null, "Edit/Edit conflict ConflictedCangeAction is NULL"); // find the target-side change action (should be a delta table entry) var changeActionQuery = context.RTChangeActionSet.Where(a => a.ChangeActionId == targetChangeActionId); if (changeActionQuery.Count() != 1) { return(false); } RTChangeAction targetChangeAction = changeActionQuery.First(); // Extract all fields updated in the target change action XmlDocument targetSideChanges = new XmlDocument(); targetSideChanges.LoadXml(targetChangeAction.ActionData); string[] targetSideChangedFields = ExtractFieldRefNames(targetSideChanges); // drop the target-side updated fields from the source-side change // example: // target side change includes Field1, Field2, Field3 // source side change includes Field1, Field2, Field5, Field 6 // By taking target, we want to migrate Field1, Field2, Field3 to source side // Then migrate Field5, Field 6 to target side, i.e. dropping Field1, Field2 DropFields(conflict.ConflictedChangeAction.MigrationActionDescription, targetSideChangedFields); // update result for source change if (!ChangeContainsFieldUpdates(conflict.ConflictedChangeAction.MigrationActionDescription)) { conflict.ConflictedChangeAction.ChangeGroup.Status = ChangeStatus.Skipped; conflict.ConflictedChangeAction.ChangeGroup.Save(); } // since we will return ConflictResolutionType.UpdatedConflictedChangeAction, conflict manager will update the conflicted change action for us return(true); } }
public override ReadOnlyCollection <KeyValuePair <MigrationAction, MigrationAction> > DetectContentConflict() { List <KeyValuePair <MigrationAction, MigrationAction> > conflictActions = new List <KeyValuePair <MigrationAction, MigrationAction> >(); Dictionary <long, SqlChangeGroup> loadedChangeGroups = new Dictionary <long, SqlChangeGroup>(); using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance()) { foreach (VCContentConflictResult contentConflictResults in context.QueryContentConflict(SourceId, new Guid(Session.SessionUniqueId))) { RTChangeAction migrationInstructionAction = context.RTChangeActionSet.Where(a => a.ChangeActionId == contentConflictResults.MigrationInstructionChangeActionId).First(); RTChangeAction deltaAction = context.RTChangeActionSet.Where(a => a.ChangeActionId == contentConflictResults.DeltaChangeActionId).First(); SqlMigrationAction conflictActionSource = SqlMigrationAction.RealizeFromDB(migrationInstructionAction); if (loadedChangeGroups.ContainsKey(migrationInstructionAction.ChangeGroupId)) { conflictActionSource.ChangeGroup = loadedChangeGroups[migrationInstructionAction.ChangeGroupId]; } else { RTChangeGroup migrationInstructionChangeGroup = context.RTChangeGroupSet.Where(c => c.Id == migrationInstructionAction.ChangeGroupId).First(); SqlChangeGroup conflictChangeGroupSource = new SqlChangeGroup(this); conflictChangeGroupSource.RealizeFromEDMWithSingleAction(migrationInstructionChangeGroup, migrationInstructionAction); loadedChangeGroups.Add(migrationInstructionAction.ChangeGroupId, conflictChangeGroupSource); conflictActionSource.ChangeGroup = conflictChangeGroupSource; } SqlMigrationAction conflictActionTarget = SqlMigrationAction.RealizeFromDB(deltaAction); if (loadedChangeGroups.ContainsKey(deltaAction.ChangeGroupId)) { conflictActionTarget.ChangeGroup = loadedChangeGroups[deltaAction.ChangeGroupId]; } else { RTChangeGroup deltaChangeGroup = context.RTChangeGroupSet.Where(c => c.Id == deltaAction.ChangeGroupId).First(); SqlChangeGroup conflictChangeGroupTarget = new SqlChangeGroup(this); conflictChangeGroupTarget.RealizeFromEDMWithSingleAction(deltaChangeGroup, deltaAction); loadedChangeGroups.Add(deltaAction.ChangeGroupId, conflictChangeGroupTarget); conflictActionTarget.ChangeGroup = conflictChangeGroupTarget; } conflictActions.Add(new KeyValuePair <MigrationAction, MigrationAction>(conflictActionSource, conflictActionTarget)); } } return(conflictActions.AsReadOnly()); }
/// <summary> /// bulk save sliced child change actions /// </summary> /// <param name="page">a page/slice of child change actions</param> internal void BatchSaveChangeActions(IList <IMigrationAction> page) { Debug.Assert(m_runTimeChangeGroup != null); const int bulkChangeActionInsertionSize = 1000; int changeActionCount = 0; int pageIndex = 0; while (pageIndex < page.Count) { using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance()) { RTChangeGroup rtChangeGroupCache = getNativeRTChangeGroup(context); Debug.Assert(null != rtChangeGroupCache); while (pageIndex < page.Count && changeActionCount < bulkChangeActionInsertionSize) { SqlMigrationAction action = page[pageIndex] as SqlMigrationAction; Debug.Assert(null != action); // cache "Dirty" flag, as assignin 'this' to its ChangeGroup will set the flag to true bool actionWasDirty = action.IsDirty; action.ChangeGroup = this; if (!action.IsPersisted) { IMigrationItemSerializer serializer = ManagerWithMigrationItemSerializers[action.Action]; action.CreateNew(serializer); context.AddToRTChangeActionSet(action.RTChangeAction); action.RTChangeAction.ChangeGroup = rtChangeGroupCache; ++changeActionCount; } else if (actionWasDirty) { IMigrationItemSerializer serializer = ManagerWithMigrationItemSerializers[action.Action]; RTChangeAction rtChangeAction = action.RTChangeAction; if (null != rtChangeAction) { rtChangeAction = context.GetObjectByKey(rtChangeAction.EntityKey) as RTChangeAction; } else { rtChangeAction = context.RTChangeActionSet.Where(ca => ca.ChangeActionId == action.ActionId).First(); } rtChangeAction.Recursivity = action.Recursive; rtChangeAction.IsSubstituted = action.State == ActionState.Skipped ? true : false; rtChangeAction.ActionId = action.Action; rtChangeAction.SourceItem = serializer.SerializeItem(action.SourceItem); rtChangeAction.ToPath = action.Path; rtChangeAction.ItemTypeReferenceName = action.ItemTypeReferenceName; rtChangeAction.FromPath = action.FromPath; rtChangeAction.Version = action.Version; rtChangeAction.MergeVersionTo = action.MergeVersionTo; if (action.MigrationActionDescription != null && action.MigrationActionDescription.DocumentElement != null) { rtChangeAction.ActionData = action.MigrationActionDescription.DocumentElement.OuterXml; } ++changeActionCount; } ++pageIndex; } context.TrySaveChanges(); changeActionCount = 0; } } }
public IMigrationAction RealizeFromEDMWithSingleAction(RTChangeGroup runTimeChangeGroup, RTChangeAction runTimeChangeAction) { RealizeChangeGroupProperties(runTimeChangeGroup); UseOtherSideMigrationItemSerializers = true; switch (Status) { case ChangeStatus.ChangeCreationInProgress: case ChangeStatus.Delta: case ChangeStatus.DeltaComplete: case ChangeStatus.DeltaPending: case ChangeStatus.DeltaSynced: UseOtherSideMigrationItemSerializers = false; break; default: break; } return(RealizeSingleActionFromEDM(runTimeChangeAction)); }
public ChangeActionViewModel(RTChangeAction changeAction) { m_changeAction = changeAction; }
internal override void CreateNew(IMigrationItemSerializer serializer) { // TODO: Consider renaming local RTChangeAction property to avoid conflict if (null == serializer) { throw new InvalidOperationException("IMigrationItem serializer is not registered"); } m_RTChangeAction = Microsoft.TeamFoundation.Migration.EntityModel.RTChangeAction.CreateRTChangeAction (ChangeGroup.ChangeGroupId, ActionId, Recursive, (State == ActionState.Skipped), 1, Action, serializer.SerializeItem(SourceItem), Path, false, ItemTypeReferenceName); m_RTChangeAction.FromPath = FromPath; m_RTChangeAction.Version = this.Version; m_RTChangeAction.MergeVersionTo = this.MergeVersionTo; if (MigrationActionDescription != null && MigrationActionDescription.DocumentElement != null) { m_RTChangeAction.ActionData = MigrationActionDescription.DocumentElement.OuterXml; } m_RTChangeAction.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(RTChangeAction_PropertyChanged); /* * Debug.Assert(ActionId == -1); * * MigrationSqlTransaction sqlTrx = (MigrationSqlTransaction)trx; * * using (SqlCommand cmd = sqlTrx.CreateCommand()) * { * cmd.CommandType = CommandType.StoredProcedure; * cmd.CommandText = "prc_iiCreateActionData"; * * cmd.Parameters.Add("@ChangeGroupID", SqlDbType.Int).Value = ChangeGroup.ChangeGroupId; * * cmd.Parameters.Add("@Order", SqlDbType.Int).Value = Order; * * cmd.Parameters.Add("@State", SqlDbType.Int).Value = State; * * cmd.Parameters.Add("@SourceItem", SqlDbType.Xml).Value * = (SourceItem != null) ? (object)ChangeGroup.Manager.SourceSerializer.SerializeItem(SourceItem) : (object)DBNull.Value; * * cmd.Parameters.Add("@TargetSourceItem", SqlDbType.Xml).Value * = (TargetSourceItem != null) ? (object)ChangeGroup.Manager.TargetSerializer.SerializeItem(TargetSourceItem) : (object)DBNull.Value; * * cmd.Parameters.Add("@TargetTargetItem", SqlDbType.Xml).Value * = (TargetTargetItem != null) ? (object)ChangeGroup.Manager.TargetSerializer.SerializeItem(TargetTargetItem) : (object)DBNull.Value; * * cmd.Parameters.Add("@BasicAction", SqlDbType.Int).Value = Action; * cmd.Parameters.Add("@Recursivity", SqlDbType.Bit).Value = Recursive; * * cmd.Parameters.Add("@Label", SqlDbType.NVarChar).Value * = (Label != null) ? Label : (object)DBNull.Value; * * cmd.Parameters.Add("@Version", SqlDbType.NVarChar).Value * = (Version != null) ? Version : (object)DBNull.Value; * * cmd.Parameters.Add("@MergeVersionTo", SqlDbType.NVarChar).Value * = (MergeVersionTo != null) ? MergeVersionTo : (object)DBNull.Value; * * int identity; * if (DataAccessManager.TryExecuteScalar<int>(cmd, out identity)) * { * ActionId = identity; * } * else * { * throw new MigrationException(MigrationToolkitResources.FailureCreatingNewActionRow); * } * }*/ }