public void AddToQueueLog(JobInstance jobInstance)
        {
            if (jobInstance == null)
            {
                throw new Exception("Job instance can not be null.");
            }

            using (var dbContext = new ls.QueueManagementDataContext(_connectionString))
            {
                var now = DateTime.Now;

                var queuedJobInstance = new ls.JobQueue();

                queuedJobInstance.JobInstanceId      = jobInstance.Id;
                queuedJobInstance.QueueRequestId     = jobInstance.QueueRequest.Id;
                queuedJobInstance.JobId              = jobInstance.Job.Id;
                queuedJobInstance.CreatedDate        = now;
                queuedJobInstance.UpdatedDate        = now;
                queuedJobInstance.SourceDataSourceId = jobInstance.SourceDataSource.DataSource.Id;
                queuedJobInstance.TargetDataSourceId = jobInstance.TargetDataSource.DataSource.Id;
                queuedJobInstance.Filters            = JobFilterHelper.GetTextForDatabase(jobInstance.Filters);
                queuedJobInstance.InvocationSource   = jobInstance.InvocationSource;
                queuedJobInstance.ScheduledStartTime = jobInstance.ScheduledStartTime;
                queuedJobInstance.ActualStartTime    = jobInstance.ActualStartTime.HasValue ? jobInstance.ActualStartTime.Value : new DateTime?();
                queuedJobInstance.IsOnDemand         = jobInstance.InvocationSourceType == JobInvocationSourceType.OnDemand ? true : false;
                queuedJobInstance.JobQueueStatusId   = (byte)jobInstance.Status;

                dbContext.JobQueues.InsertOnSubmit(queuedJobInstance);

                dbContext.SubmitChanges();

                foreach (var jobStepInstance in jobInstance.JobStepInstances)
                {
                    var queuedJobStepInstance = new ls.JobStepQueue();

                    queuedJobStepInstance.JobStepInstanceId    = jobStepInstance.Id;
                    queuedJobStepInstance.JobInstanceId        = jobInstance.Id;
                    queuedJobStepInstance.JobStepId            = jobStepInstance.JobStep.Id;
                    queuedJobStepInstance.CreatedDate          = now;
                    queuedJobStepInstance.UpdatedDate          = now;
                    queuedJobStepInstance.ActualStartTime      = jobStepInstance.ActualStartTime.HasValue ? jobStepInstance.ActualStartTime.Value : new DateTime?();
                    queuedJobStepInstance.ActualEndTime        = jobStepInstance.ActualEndTime.HasValue ? jobStepInstance.ActualEndTime.Value : new DateTime?();
                    queuedJobStepInstance.OrderIndex           = (byte)jobStepInstance.OrderIndex;
                    queuedJobStepInstance.JobStepQueueStatusId = (byte)jobStepInstance.Status;

                    dbContext.JobStepQueues.InsertOnSubmit(queuedJobStepInstance);
                }

                dbContext.SubmitChanges();
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="jobInstanceId"></param>
        /// <returns>Returns null if a "sync object" no longer exists.</returns>
        public JobInstance GetJobInstanceFromQueueLog(Guid jobInstanceId, bool throwExceptionIfSyncObjectsAreDeletedOrDisabled = false)
        {
            if (!JobQueueManager.IsSafeForQueueLogRetrieval)
            {
                throw new Exception("The Job Queue Manager is in an unsafe state as job statuses may change. Queue retrieval from the database is disallowed.");
            }

            var configurator = new SyncEngineDatabaseConfigurator(_connectionString);

            using (var dbContext = new ls.QueueManagementDataContext(_connectionString))
            {
                var jobInstanceInDbQueue = dbContext.JobQueues.Where(d => d.JobInstanceId == jobInstanceId).FirstOrDefault();

                var integration = configurator.GetIntegrationByJobId(jobInstanceInDbQueue.JobId);

                if (integration == null || !integration.IsEnabled)
                {
                    goto SyncObjectsForJobInstanceHaveChanged;
                }

                var job = integration.Jobs.Where(d => d.Id == jobInstanceInDbQueue.JobId).FirstOrDefault();

                if (job == null || !job.IsEnabled)
                {
                    goto SyncObjectsForJobInstanceHaveChanged;
                }

                var sourceDataSource = job.SourceDataSources.Values.Where(d => d.Id == jobInstanceInDbQueue.SourceDataSourceId).FirstOrDefault();

                if (sourceDataSource == null)
                {
                    goto SyncObjectsForJobInstanceHaveChanged;
                }

                if (job.TargetDataSource.Id != jobInstanceInDbQueue.TargetDataSourceId)
                {
                    goto SyncObjectsForJobInstanceHaveChanged;
                }

                var jobStepInstancesInDbQueue = dbContext.JobStepQueues.Where(d => d.JobInstanceId == jobInstanceInDbQueue.JobInstanceId).ToList();

                if (jobStepInstancesInDbQueue.Count == 0)
                {
                    goto SyncObjectsForJobInstanceHaveChanged;
                }

                List <JobStepInstance> jobStepInstanceObjs = new List <JobStepInstance>();

                foreach (var jobStepInstanceInDbQueue in jobStepInstancesInDbQueue)
                {
                    var jobStep = job.Steps.Where(d => d.Id == jobStepInstanceInDbQueue.JobStepId).FirstOrDefault();

                    if (jobStep == null || !jobStep.IsEnabled)
                    {
                        goto SyncObjectsForJobInstanceHaveChanged;
                    }

                    var jobStepInstanceObj = new JobStepInstance(jobStepInstanceInDbQueue.JobStepInstanceId, jobStep, jobStepInstanceInDbQueue.OrderIndex);

                    jobStepInstanceObj.Status = (JobStepQueueStatus)jobStepInstanceInDbQueue.JobStepQueueStatusId;

                    jobStepInstanceObjs.Add(jobStepInstanceObj);
                }

                var filters = JobFilterHelper.ParseFromDatabaseText(jobInstanceInDbQueue.Filters);

                var invocationSourceType = jobInstanceInDbQueue.IsOnDemand == true ? JobInvocationSourceType.OnDemand : JobInvocationSourceType.Scheduled;

                var queueRequest = new JobQueueRequest(jobInstanceInDbQueue.QueueRequestId, integration, job, invocationSourceType);

                var jobInstanceObj = new JobInstance(queueRequest, jobInstanceInDbQueue.JobInstanceId, integration, job, sourceDataSource, job.TargetDataSource,
                                                     jobStepInstanceObjs, jobInstanceInDbQueue.ScheduledStartTime,
                                                     jobInstanceInDbQueue.InvocationSource, invocationSourceType, filters.ToList());

                queueRequest.JobInstances.Add(jobInstanceObj);

                jobInstanceObj.Status = (JobQueueStatus)jobInstanceInDbQueue.JobQueueStatusId;

                return(jobInstanceObj);

SyncObjectsForJobInstanceHaveChanged:

                if (throwExceptionIfSyncObjectsAreDeletedOrDisabled)
                {
                    throw new Exception(string.Format("Queued job '{0}' in database logger has changed sync objects.", jobInstanceInDbQueue.JobInstanceId));
                }
                else
                {
                    return(null);
                }
            }
        }
        public void MoveToHistoryLog(JobInstance jobInstance)
        {
            if (jobInstance == null)
            {
                throw new Exception("Job instance can not be null.");
            }

            using (var dbContext = new ls.QueueManagementDataContext(_connectionString))
            {
                var now = DateTime.Now;

                var jobHistory = new ls.JobHistory();

                jobHistory.JobInstanceId      = jobInstance.Id;
                jobHistory.QueueRequestId     = jobInstance.QueueRequest.Id;
                jobHistory.JobId              = jobInstance.Job.Id;
                jobHistory.CreatedDate        = now;
                jobHistory.UpdatedDate        = now;
                jobHistory.SourceDataSourceId = jobInstance.SourceDataSource.DataSource.Id;
                jobHistory.TargetDataSourceId = jobInstance.TargetDataSource.DataSource.Id;
                jobHistory.Filters            = JobFilterHelper.GetTextForDatabase(jobInstance.Filters);
                jobHistory.InvocationSource   = jobInstance.InvocationSource;
                jobHistory.ScheduledStartTime = jobInstance.ScheduledStartTime;
                jobHistory.ActualStartTime    = jobInstance.ActualStartTime.HasValue ? jobInstance.ActualStartTime.Value : new DateTime?();

                if (jobInstance.TimeToStartDelay.HasValue && jobInstance.TimeToStartDelay.Value.Hours > 23)
                {
                    jobHistory.TimeToStartDelay = new TimeSpan(23, 59, 59);
                }
                else if (jobInstance.TimeToStartDelay.HasValue)
                {
                    jobHistory.TimeToStartDelay = jobInstance.TimeToStartDelay.Value;
                }
                else
                {
                    jobHistory.TimeToStartDelay = new TimeSpan(0, 0, 0);
                }

                jobHistory.ActualEndTime = jobInstance.ActualEndTime.HasValue ? jobInstance.ActualEndTime.Value : new DateTime?();

                if (jobInstance.ActualDuration.HasValue && jobInstance.ActualDuration.Value.Hours > 23)
                {
                    jobHistory.ActualDuration = new TimeSpan(23, 59, 59);
                }
                else if (jobInstance.ActualDuration.HasValue)
                {
                    jobHistory.ActualDuration = jobInstance.ActualDuration.Value;
                }
                else
                {
                    jobHistory.ActualDuration = new TimeSpan(0, 0, 0);
                }

                jobHistory.IsOnDemand       = jobInstance.InvocationSourceType == JobInvocationSourceType.OnDemand ? true : false;
                jobHistory.JobQueueStatusId = (byte)jobInstance.Status;
                jobHistory.HasRecordErrors  = jobInstance.HasRecordErrors;
                jobHistory.HasRuntimeErrors = jobInstance.HasRuntimeErrors;

                dbContext.JobHistories.InsertOnSubmit(jobHistory);

                dbContext.SubmitChanges();

                foreach (var jobStepInstance in jobInstance.JobStepInstances)
                {
                    var jobStepHistory = new ls.JobStepHistory();

                    jobStepHistory.JobHistoryId      = jobHistory.JobHistoryId;
                    jobStepHistory.JobStepInstanceId = jobStepInstance.Id;
                    jobStepHistory.JobInstanceId     = jobInstance.Id;
                    jobStepHistory.JobStepId         = jobStepInstance.JobStep.Id;
                    jobStepHistory.CreatedDate       = now;
                    jobStepHistory.UpdatedDate       = now;
                    jobStepHistory.ActualStartTime   = jobStepInstance.ActualStartTime.HasValue ? jobStepInstance.ActualStartTime.Value : new DateTime?();
                    jobStepHistory.ActualEndTime     = jobStepInstance.ActualEndTime.HasValue ? jobStepInstance.ActualEndTime.Value : new DateTime?();

                    if (jobStepInstance.ActualDuration.HasValue && jobStepInstance.ActualDuration.Value.Hours > 23)
                    {
                        jobStepHistory.ActualDuration = new TimeSpan(23, 59, 59);
                    }
                    else if (jobStepInstance.ActualDuration.HasValue)
                    {
                        jobStepHistory.ActualDuration = jobStepInstance.ActualDuration.Value;
                    }
                    else
                    {
                        jobStepHistory.ActualDuration = new TimeSpan(0, 0, 0);
                    }

                    jobStepHistory.OrderIndex           = (byte)jobStepInstance.OrderIndex;
                    jobStepHistory.JobStepQueueStatusId = (byte)jobStepInstance.Status;
                    jobStepHistory.HasRecordErrors      = jobStepInstance.HasRecordErrors;
                    jobStepHistory.HasRuntimeErrors     = jobStepInstance.HasRuntimeErrors;

                    dbContext.JobStepHistories.InsertOnSubmit(jobStepHistory);
                }

                dbContext.SubmitChanges();

                DeleteFromQueueLog(jobInstance.Id);
            }
        }