private void UpdateItemConversionHistory(
            RTConversionHistory rtConvHist,
            RuntimeEntityModel context)
        {
            foreach (ItemConversionHistory hist in ItemConversionHistory)
            {
                if (string.IsNullOrEmpty(hist.SourceItemId) ||
                    string.IsNullOrEmpty(hist.TargetItemId))
                {
                    throw new MigrationException(MigrationToolkitResources.InvalidConversionHistoryInfo);
                }

                string sourceItemVersionStr = string.IsNullOrEmpty(hist.SourceItemVersion)
                                               ? Constants.ChangeGroupGenericVersionNumber
                                               : hist.SourceItemVersion;
                RTMigrationItem sourceItem = FindCreateMigrationItem(
                    SourceSideSourceId,
                    hist.SourceItemId,
                    sourceItemVersionStr,
                    context);

                string targetItemVersionStr = string.IsNullOrEmpty(hist.TargetItemVersion)
                                               ? Constants.ChangeGroupGenericVersionNumber
                                               : hist.TargetItemVersion;
                RTMigrationItem targetItem = FindCreateMigrationItem(
                    TargetSideSourceId,
                    hist.TargetItemId,
                    targetItemVersionStr,
                    context);

                context.TrySaveChanges();

                // check if the pair is already in the item_revision_pair table
                var pairWithSourceItemQuery =
                    from p in context.RTItemRevisionPairSet
                    where (p.LeftMigrationItemId == sourceItem.Id || p.RightMigrationItemId == sourceItem.Id)
                    select p;
                if (pairWithSourceItemQuery.Count() > 0)
                {
                    var targetItemInPairQuery =
                        from p in pairWithSourceItemQuery
                        where p.LeftMigrationItemId == targetItem.Id || p.RightMigrationItemId == targetItem.Id
                        select p;

                    if (targetItemInPairQuery.Count() > 0)
                    {
                        continue;
                    }
                }

                RTItemRevisionPair pair = RTItemRevisionPair.CreateRTItemRevisionPair(
                    sourceItem.Id, targetItem.Id);
                pair.LeftMigrationItem  = sourceItem;
                pair.RightMigrationItem = targetItem;
                pair.ConversionHistory  = rtConvHist;
            }
        }
        private RTConversionHistory UpdateGroupConvHist(
            RuntimeEntityModel context,
            RTSessionRun rtSessionRun,
            RTMigrationSource rtMigrationSource)
        {
            RTConversionHistory runTimeConverHistory = RTConversionHistory.CreateRTConversionHistory(
                DateTime.UtcNow,
                -1,
                false);

            runTimeConverHistory.SessionRun            = rtSessionRun;
            runTimeConverHistory.SourceMigrationSource = rtMigrationSource;

            context.AddToRTConversionHistorySet(runTimeConverHistory);
            return(runTimeConverHistory);
        }
        /// <summary>
        /// Saves the conversion history and associate it with a particular session run and migration source;
        /// Additionally, mark the Reflected Change Group (the delta table entry of this processed change group) to be sync-ed.
        /// </summary>
        /// <param name="sessionRunId">int.MinValue if sessionRunId is not available</param>
        /// <param name="migrationSourceId"></param>
        /// <param name="sessionId"></param>
        /// <param name="reflectedChangeGroupId"></param>
        /// <returns></returns>
        internal bool Save(
            int sessionRunId,
            Guid migrationSourceId,
            Guid sessionId,
            long?reflectedChangeGroupId)
        {
            if (string.IsNullOrEmpty(ChangeId))
            {
                return(false);
            }

            using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance())
            {
                if (ItemConversionHistory.Count > 0)
                {
                    var sessionRunQuery = (sessionRunId == int.MinValue)
                        ? from sr in context.RTSessionRunSet
                                          where sr.Config.LeftSourceConfig.MigrationSource.UniqueId.Equals(migrationSourceId) ||
                                          sr.Config.RightSourceConfig.MigrationSource.UniqueId.Equals(migrationSourceId)
                                          select sr
                        : context.RTSessionRunSet.Where(sr => sr.Id == sessionRunId);
                    if (sessionRunQuery.Count() == 0)
                    {
                        return(false);
                    }
                    RTSessionRun rtSessionRun = sessionRunQuery.First();

                    var migrationSourceQuery = context.RTMigrationSourceSet.Where(ms => ms.UniqueId.Equals(migrationSourceId));
                    if (migrationSourceQuery.Count() == 0)
                    {
                        return(false);
                    }
                    RTMigrationSource rtMigrationSource = migrationSourceQuery.First();

                    RTConversionHistory rtConvHist = UpdateGroupConvHist(context, rtSessionRun, rtMigrationSource);
                    UpdateItemConversionHistory(rtConvHist, context);
                }

                if (!sessionId.Equals(Guid.Empty) && reflectedChangeGroupId.HasValue)
                {
                    MarkDeltaTableSynced(context, sessionId, reflectedChangeGroupId.Value);
                }

                context.TrySaveChanges();
                return(true);
            }
        }
        private bool updateConversionHistory(MigrationConflict conflict, ConflictResolutionRule rule)
        {
            if (!rule.DataFieldDictionary.ContainsKey(VCContentConflictUserMergeChangeAction.MigrationInstructionChangeId) ||
                !rule.DataFieldDictionary.ContainsKey(VCContentConflictUserMergeChangeAction.DeltaTableChangeId))
            {
                return(false);
            }
            string migrationInstructionName = rule.DataFieldDictionary[VCContentConflictUserMergeChangeAction.MigrationInstructionChangeId];
            string deltaTableName           = rule.DataFieldDictionary[VCContentConflictUserMergeChangeAction.DeltaTableChangeId];

            using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance())
            {
                ChangeGroup conflictChangeGroup = conflict.ConflictedChangeAction.ChangeGroup;
                Guid        deltaSideSourceId;

                // Mark all delta table entry as DeltaComplete
                var deltaTableEntries =
                    from d in context.RTChangeGroupSet
                    where d.SessionUniqueId == conflictChangeGroup.SessionId &&
                    d.Status == (int)ChangeStatus.DeltaPending
                    select d;
                foreach (RTChangeGroup deltaTableEntry in deltaTableEntries)
                {
                    deltaTableEntry.Status = (int)ChangeStatus.DeltaComplete;
                    deltaTableEntry.ContainsBackloggedAction = false;
                }

                // Mark all migration instruction entry as Complete
                var migrationInstructionEntries =
                    from d in context.RTChangeGroupSet
                    where d.SessionUniqueId == conflictChangeGroup.SessionId &&
                    (d.Status == (int)ChangeStatus.Pending || d.Status == (int)ChangeStatus.InProgress || d.Status == (int)ChangeStatus.PendingConflictDetection)
                    select d;
                foreach (RTChangeGroup migrationInstructionEntry in migrationInstructionEntries)
                {
                    migrationInstructionEntry.Status = (int)ChangeStatus.Complete;
                    migrationInstructionEntry.ContainsBackloggedAction = false;
                }

                // Mark the source side highwatermark
                var sourceSideHighWaterMark =
                    (from hwm in context.RTHighWaterMarkSet
                     where hwm.SessionUniqueId == conflictChangeGroup.SessionId &&
                     hwm.SourceUniqueId != conflictChangeGroup.SourceId &&
                     hwm.Name == Constants.HwmDelta
                     select hwm).First();
                Debug.Assert(sourceSideHighWaterMark != null, "Can't find the source side HWM");

                sourceSideHighWaterMark.Value = deltaTableName;
                deltaSideSourceId             = sourceSideHighWaterMark.SourceUniqueId;

                // Mark the target side highwatermark
                var targetHighWaterMark =
                    (from hwm in context.RTHighWaterMarkSet
                     where hwm.SessionUniqueId == conflictChangeGroup.SessionId &&
                     hwm.SourceUniqueId == conflictChangeGroup.SourceId &&
                     hwm.Name == Constants.HwmDelta
                     select hwm).First();
                Debug.Assert(targetHighWaterMark != null, "Can't find the target side HWM");

                targetHighWaterMark.Value = migrationInstructionName;

                // Create the conversion history entry
                RTConversionHistory conversionHistory = RTConversionHistory.CreateRTConversionHistory(
                    DateTime.UtcNow,
                    -1,
                    true);
                conversionHistory.Comment = rule.RuleDescription;

                var session =
                    (from s in context.RTSessionConfigSet
                     where s.SessionUniqueId == conflictChangeGroup.SessionId
                     select s).First();

                Debug.Assert(session != null, "Cannot find session in DB");

                RTSessionRun sessionRun =
                    (from sr in context.RTSessionRunSet
                     where sr.Id == session.Id
                     select sr).First();
                Debug.Assert(sessionRun != null, "Cannot find session run in DB");

                conversionHistory.SessionRun = sessionRun;

                RTMigrationSource migrationSource =
                    (from ms in context.RTMigrationSourceSet
                     where ms.UniqueId.Equals(conflictChangeGroup.SourceId)
                     select ms).First();
                Debug.Assert(migrationSource != null, "Cannot find the migration source to persist conversion history");

                RTMigrationSource deltaSideMigrationSource =
                    (from ms in context.RTMigrationSourceSet
                     where ms.UniqueId.Equals(deltaSideSourceId)
                     select ms).First();
                Debug.Assert(deltaSideMigrationSource != null, "Cannot find the migration source to persist conversion history");

                conversionHistory.SourceMigrationSource = migrationSource;

                context.AddToRTConversionHistorySet(conversionHistory);

                RTMigrationItem sourceItem = RTMigrationItem.CreateRTMigrationItem(0, deltaTableName, Constants.ChangeGroupGenericVersionNumber);
                sourceItem.MigrationSource = migrationSource;
                RTMigrationItem targetItem = RTMigrationItem.CreateRTMigrationItem(0, migrationInstructionName, Constants.ChangeGroupGenericVersionNumber);
                targetItem.MigrationSource = deltaSideMigrationSource;


                RTItemRevisionPair pair = RTItemRevisionPair.CreateRTItemRevisionPair(
                    sourceItem.Id, targetItem.Id);
                pair.LeftMigrationItem  = sourceItem;
                pair.RightMigrationItem = targetItem;
                pair.ConversionHistory  = conversionHistory;



                // Create a new HistoryNotFoundConflict Resolution Rule
                context.TrySaveChanges();
            }
            return(true);
        }
Example #5
0
        /// <summary>
        /// Update the conversion history with the given migration instruction and delta table entry. This will add the entry to conversion history and remove all pending change groups.
        /// </summary>
        /// <param name="migrationInstructionName"></param>
        /// <param name="deltaTableName"></param>
        /// <param name="comment"></param>
        /// <returns></returns>
        public override bool UpdateConversionHistoryAndRemovePendingChangeGroups(string migrationInstructionName, string deltaTableName, string comment)
        {
            if (string.IsNullOrEmpty(migrationInstructionName) || (string.IsNullOrEmpty(deltaTableName)))
            {
                return(false);
            }

            using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance())
            {
                Guid deltaSideSourceId;
                Guid sessionId = new Guid(Session.SessionUniqueId);

                // Mark all delta table entry as DeltaComplete
                var deltaTableEntries =
                    from d in context.RTChangeGroupSet
                    where d.SessionUniqueId == sessionId &&
                    d.Status == (int)ChangeStatus.DeltaPending
                    select d;
                foreach (RTChangeGroup deltaTableEntry in deltaTableEntries)
                {
                    deltaTableEntry.Status = (int)ChangeStatus.DeltaComplete;
                    deltaTableEntry.ContainsBackloggedAction = false;
                }

                // Mark all migration instruction entry as Complete
                var migrationInstructionEntries =
                    from d in context.RTChangeGroupSet
                    where d.SessionUniqueId == sessionId &&
                    (d.Status == (int)ChangeStatus.Pending || d.Status == (int)ChangeStatus.InProgress || d.Status == (int)ChangeStatus.PendingConflictDetection)
                    select d;
                foreach (RTChangeGroup migrationInstructionEntry in migrationInstructionEntries)
                {
                    migrationInstructionEntry.Status = (int)ChangeStatus.Complete;
                    migrationInstructionEntry.ContainsBackloggedAction = false;
                }

                // Mark the source side highwatermark
                var sourceSideHighWaterMark =
                    (from hwm in context.RTHighWaterMarkSet
                     where hwm.SessionUniqueId == sessionId &&
                     hwm.SourceUniqueId != SourceId &&
                     hwm.Name == Constants.HwmDelta
                     select hwm).First();
                Debug.Assert(sourceSideHighWaterMark != null, "Can't find the source side HWM");

                sourceSideHighWaterMark.Value = deltaTableName;
                deltaSideSourceId             = sourceSideHighWaterMark.SourceUniqueId;

                // Mark the target side highwatermark
                var targetHighWaterMark =
                    (from hwm in context.RTHighWaterMarkSet
                     where hwm.SessionUniqueId == sessionId &&
                     hwm.SourceUniqueId == SourceId &&
                     hwm.Name == Constants.HwmDelta
                     select hwm).First();
                Debug.Assert(targetHighWaterMark != null, "Can't find the target side HWM");

                targetHighWaterMark.Value = migrationInstructionName;

                // Prepare to create the conversion history entry (unless a matching one exists)
                RTMigrationSource migrationSource =
                    (from ms in context.RTMigrationSourceSet
                     where ms.UniqueId.Equals(SourceId)
                     select ms).First();
                Debug.Assert(migrationSource != null, "Cannot find the migration source to persist conversion history");

                RTMigrationSource deltaSideMigrationSource =
                    (from ms in context.RTMigrationSourceSet
                     where ms.UniqueId.Equals(deltaSideSourceId)
                     select ms).First();
                Debug.Assert(deltaSideMigrationSource != null, "Cannot find the migration source to persist conversion history");

                // A MigrationItem row may already exist; if so use it
                bool sourceMigrationItemExists;
                var  sourceItemQuery = (from mi in context.RTMigrationItemSet
                                        where mi.MigrationSource.UniqueId.Equals(migrationSource.UniqueId) &&
                                        mi.ItemId == deltaTableName &&
                                        mi.ItemVersion == Constants.ChangeGroupGenericVersionNumber
                                        select mi);
                RTMigrationItem sourceItem;
                if (sourceItemQuery.Count() > 0)
                {
                    sourceItem = sourceItemQuery.First();
                    sourceMigrationItemExists = true;
                }
                else
                {
                    sourceItem = RTMigrationItem.CreateRTMigrationItem(0, deltaTableName, Constants.ChangeGroupGenericVersionNumber);
                    sourceItem.MigrationSource = migrationSource;
                    sourceMigrationItemExists  = false;
                }

                // A MigrationItem row may already exist; if so use it
                bool targetMigrationItemExists;
                var  targetItemQuery = (from mi in context.RTMigrationItemSet
                                        where mi.MigrationSource.UniqueId.Equals(deltaSideMigrationSource.UniqueId) &&
                                        mi.ItemId == migrationInstructionName &&
                                        mi.ItemVersion == Constants.ChangeGroupGenericVersionNumber
                                        select mi);
                RTMigrationItem targetItem;
                if (targetItemQuery.Count() > 0)
                {
                    targetItem = targetItemQuery.First();
                    targetMigrationItemExists = true;
                }
                else
                {
                    targetItem = RTMigrationItem.CreateRTMigrationItem(0, migrationInstructionName, Constants.ChangeGroupGenericVersionNumber);
                    targetItem.MigrationSource = deltaSideMigrationSource;
                    targetMigrationItemExists  = false;
                }

                // If both the source and target migration items exist in the DB, there is no need to create a duplicate conversion
                // history record, and attempting to do so will cause a constraint violation.
                if (!sourceMigrationItemExists || !targetMigrationItemExists)
                {
                    // Create the conversion history entry
                    RTConversionHistory conversionHistory = RTConversionHistory.CreateRTConversionHistory(
                        DateTime.UtcNow,
                        -1,
                        true);
                    conversionHistory.Comment = comment;

                    var session =
                        (from s in context.RTSessionConfigSet
                         where s.SessionUniqueId == sessionId
                         select s).First();

                    Debug.Assert(session != null, "Cannot find session in DB");

                    RTSessionRun sessionRun =
                        (from sr in context.RTSessionRunSet
                         where sr.Id == session.Id
                         select sr).First();
                    Debug.Assert(sessionRun != null, "Cannot find session run in DB");

                    conversionHistory.SessionRun            = sessionRun;
                    conversionHistory.SourceMigrationSource = migrationSource;
                    context.AddToRTConversionHistorySet(conversionHistory);

                    RTItemRevisionPair pair = RTItemRevisionPair.CreateRTItemRevisionPair(
                        sourceItem.Id, targetItem.Id);
                    pair.LeftMigrationItem  = sourceItem;
                    pair.RightMigrationItem = targetItem;
                    pair.ConversionHistory  = conversionHistory;
                }

                // Create a new HistoryNotFoundConflict Resolution Rule
                context.TrySaveChanges();
            }
            return(true);
        }