public ReadOnlyCollection <LinkChangeGroup> GenerateNextLinkDeltaSlice( LinkService linkService, int maxDeltaSliceSize) { try { var linkChangeGroups = new List <LinkChangeGroup>(); if (null == ExtractLinkChangeActionsCallback) { return(linkChangeGroups.AsReadOnly()); } // load high watermark; as for CQ, we store local time for queries m_hwmLink.Reload(); DateTime hwmDeltaValue = m_hwmLink.Value; if (hwmDeltaValue.Equals(default(DateTime))) { hwmDeltaValue = new DateTime(1900, 1, 1); } hwmDeltaValue = hwmDeltaValue.AddSeconds(-1); // go back 1 second as we'll drop the millisec below string hwmDeltaValueStr = hwmDeltaValue.ToString(m_migrationContext.CQQueryDateTimeFormat, CultureInfo.InvariantCulture); // record current time to update HWM after processing DateTime newHwmValue = CQUtilityMethods.GetTimeForNewHighWaterMark(m_migrationContext.CQTimeOffsetFromServerHistoryTimesInMinutes); // store to be used for analysis WorkItemLinkStore store = new WorkItemLinkStore(m_configurationService.SourceId); // extract links var inMaxDeltaSliceSize = maxDeltaSliceSize; foreach (CQRecordFilter filter in m_filters) { CQRecordQueryBase recordQuery = CQRecordQueryFactory.CreateQuery(m_userSession, filter, hwmDeltaValueStr, this); foreach (ClearQuestOleServer.OAdEntity record in recordQuery) { // HACK HACK if (record == null) { continue; } // HACK HACK string recDispName = CQWrapper.GetEntityDisplayName(record); TraceManager.TraceInformation("Generating linking delta for CQ Record: {0}", recDispName); var perWorkItemlinkChangeGroups = new List <LinkChangeGroup>(); ExtractLinkChangeActionsCallback(m_userSession, record, perWorkItemlinkChangeGroups); if (perWorkItemlinkChangeGroups.Count == 0) { TraceManager.TraceInformation("Number of links: {0}", 0); continue; } LinkChangeGroup consolidatedLinkChangeGroup = perWorkItemlinkChangeGroups[0]; for (int i = 1; i < perWorkItemlinkChangeGroups.Count; ++i) { foreach (LinkChangeAction action in perWorkItemlinkChangeGroups[i].Actions) { consolidatedLinkChangeGroup.AddChangeAction(action); } } TraceManager.TraceInformation("Number of links: {0}", consolidatedLinkChangeGroup.Actions.Count.ToString()); // VERY IMPORTANT STEP: update the link delta to store string hostRecMigrItemId = UtilityMethods.CreateCQRecordMigrationItemId(record); store.UpdatePerItemLinkChangeGroupsByCheckingRelatedItemRecords( hostRecMigrItemId, consolidatedLinkChangeGroup, this); if (consolidatedLinkChangeGroup.Actions.Count > 0) { linkChangeGroups.Add(consolidatedLinkChangeGroup); } maxDeltaSliceSize -= consolidatedLinkChangeGroup.Actions.Count; if (maxDeltaSliceSize <= 0) { // size limit reached - persist groups to DB, then empty the slice and process next slice linkService.AddChangeGroups(linkChangeGroups); linkChangeGroups.Clear(); maxDeltaSliceSize = inMaxDeltaSliceSize; } } } // persist remaining groups to DB linkService.AddChangeGroups(linkChangeGroups); // clean up the returned link change group collection // when the caller (toolkit) receives an empty collection, it understands there is no more // delta to generate for the moment, and proceeds to next phase linkChangeGroups.Clear(); // update primary Highwater Mark m_hwmLink.Update(newHwmValue); TraceManager.TraceInformation("Persisted CQ linking HWM: {0}", ClearQuestConstants.CqLinkHwm); TraceManager.TraceInformation("Updated CQ linking HWM: {0}", newHwmValue.ToString()); return(linkChangeGroups.AsReadOnly()); } catch (Exception exception) { // [teyang] TODO CONFLICT HANDLING //MigrationConflict genericeConflict = WitGeneralConflictType.CreateConflict(exception); //var conflictManager = m_conflictManager.GetService(typeof(ConflictManager)) as ConflictManager; //Debug.Assert(null != conflictManager); //List<MigrationAction> resolutionActions; //ConflictResolutionResult resolveRslt = // conflictManager.TryResolveNewConflict(conflictManager.SourceId, genericeConflict, out resolutionActions); //Debug.Assert(!resolveRslt.Resolved); TraceManager.TraceException(exception); return(new List <LinkChangeGroup>().AsReadOnly()); } }
public void GenerateDeltaTable() { try { if (!m_isLoginUserSQLEditor) { ValidateIsSQLEditor(); m_isLoginUserSQLEditor = true; } // load high watermark; as for CQ, we store local time for queries m_hwmDelta.Reload(); DateTime hwmDeltaValue = m_hwmDelta.Value; if (hwmDeltaValue.Equals(default(DateTime))) { hwmDeltaValue = new DateTime(1900, 1, 1); } hwmDeltaValue = hwmDeltaValue.AddSeconds(-1); // go back 1 second as we'll drop the millisec below m_migrationContext.CurrentHWMBaseLine = hwmDeltaValue; string hwmDeltaValueStr = hwmDeltaValue.ToString(m_migrationContext.CQQueryDateTimeFormat, CultureInfo.InvariantCulture); DateTime newHwmValue = CQUtilityMethods.GetTimeForNewHighWaterMark(m_migrationContext.CQTimeOffsetFromServerHistoryTimesInMinutes); foreach (CQRecordFilter filter in m_filters) { ComputeDeltaPerRecordType(filter, hwmDeltaValueStr); } // persist results and hwm TraceManager.TraceInformation("Promote delta to pending."); m_changeGroupService.PromoteDeltaToPending(); m_hwmDelta.Update(newHwmValue); TraceManager.TraceInformation("Persisted CQ HWM: {0}", ClearQuestConstants.CqRecordHwm); TraceManager.TraceInformation("Updated CQ HWM: {0}", newHwmValue.ToString()); } catch (ClearQuestInsufficientPrivilegeException privEx) { ConflictResolutionResult rslt = UtilityMethods.HandleInsufficientPriviledgeException(privEx, m_conflictManagerService); if (rslt.Resolved) { // todo: currently not expected, as we only enabled manual/skip resolution action } } catch (ClearQuestCOMDllNotFoundException cqComNotFoundEx) { UtilityMethods.HandleCOMDllNotFoundException(cqComNotFoundEx, ErrorManager, m_conflictManagerService); } catch (ClearQuestCOMCallException cqComCallEx) { UtilityMethods.HandleCQComCallException(cqComCallEx, ErrorManager, m_conflictManagerService); } catch (Exception ex) { ErrorManager errMgr = null; if (m_analysisServiceContainer != null) { errMgr = m_analysisServiceContainer.GetService(typeof(ErrorManager)) as ErrorManager; } UtilityMethods.HandleGeneralException(ex, errMgr, m_conflictManagerService); } }