This commit is contained in:
Zeeshaun
2026-03-24 15:26:03 -05:00
parent 1e5beb292a
commit 9cc87337b8
333 changed files with 17931 additions and 0 deletions
@@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Linq;
using LCU.Library.Internal.DispatcherModels.Entities;
using LCU.Library.Internal.DispatcherModels.Models;
namespace LCU.Api.Internal.DispatcherLib.Extensions.Enumerables;
public static class StatusTypeMatch
{
public static IQueryable<Job> FilterByStatusType(this IQueryable<Job> jobs, Filter filter)
{
if (filter?.StatusFilters == null || !filter.StatusFilters.Any())
{
return jobs;
}
var enabledStatuses = filter.StatusFilters.Where(statusFilter => statusFilter.IsEnabled).Select(j => j.JobStatus).ToList();
if (!enabledStatuses.Any())
{
return jobs;
}
return jobs.Where(job => enabledStatuses.Contains(job.JobStatus));
}
}
@@ -0,0 +1,18 @@
using System.Linq;
using Microsoft.EntityFrameworkCore;
using LCU.Library.Internal.DispatcherModels.Models;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Extensions.Queryables;
public static class ContainsTagIdQueryable
{
public static IQueryable<Job> FilterOnTagId(this IQueryable<Job> queryable, Filter filter)
{
if (filter?.TagIdFilters == null || !filter.TagIdFilters.Any())
{
return queryable;
}
return queryable.Where(job => job.JobTags.Any(jobTag => filter.TagIdFilters.Contains(jobTag.TagId)));
}
}
@@ -0,0 +1,70 @@
using System.Linq;
using Microsoft.EntityFrameworkCore;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Extensions.Queryables;
public static class IncludeAllQueryable
{
/// <summary>
/// Since this runs as Split Query, the OrderyByDescending only works during the querying but not in our result set.
/// OrderbyDescending on WorkItemExecutions will have to be done prior to use if need be.
/// </summary>
/// <param name="queryable"></param>
/// <param name="numberOfWorkItems"></param>
/// <returns></returns>
public static IQueryable<Job> IncludeAll(this IQueryable<Job> queryable, int numberOfWorkItemExecutions, int numberOfExecutionMessages)
{
return queryable.Include(job => job.WorkItems)
.ThenInclude(wi => wi.WorkItemExecutions
.OrderByDescending(workItemExecution => workItemExecution.StartedTimestamp)
.Take(numberOfWorkItemExecutions))
.ThenInclude(workItemExecution => workItemExecution.ExecutionMessages
.OrderByDescending(executionMessage => executionMessage.MessageDate)
.Take(numberOfExecutionMessages))
.Include(job => job.JobErrorRecipients)
.Include(jobTag => jobTag.JobTags)
.ThenInclude(jobTag => jobTag.Tag)
.AsSplitQuery();
}
public static IQueryable<Job> IncludeErrorRecipients(this IQueryable<Job> queryable)
{
return queryable.Include(job => job.JobErrorRecipients);
}
public static IQueryable<WorkItem> IncludeAll(this IQueryable<WorkItem> queryable)
{
return queryable.Include(workItem => workItem.WorkItemExecutions);
}
public static IQueryable<WorkItem> IncludeAll(this IQueryable<WorkItem> queryable, int numberOfWorkItemExecutions, int numberOfExecutionMessages)
{
return queryable.Include(wi => wi.WorkItemExecutions
.OrderByDescending(workItemExecution => workItemExecution.StartedTimestamp)
.Take(numberOfWorkItemExecutions))
.ThenInclude(workItemExecution => workItemExecution.ExecutionMessages
.OrderByDescending(executionMessage => executionMessage.MessageDate)
.Take(numberOfExecutionMessages));
}
public static IQueryable<JobTag> IncludeAll(this IQueryable<JobTag> queryable)
{
return queryable.Include(jobTag => jobTag.Tag);
}
public static IQueryable<WorkItemExecution> IncludeAll(this IQueryable<WorkItemExecution> queryable)
{
return queryable.Include(workItemExecution => workItemExecution.ExecutionMessages);
}
public static IQueryable<CleanUpJobSetting> IncludeAll(this IQueryable<CleanUpJobSetting> queryable)
{
return queryable.Include(cleanUpJobSetting => cleanUpJobSetting.CleanUpJobTags)
.ThenInclude(cleanUpJobTag => cleanUpJobTag.Tag);
}
public static IQueryable<CleanUpJobTag> IncludeAll(this IQueryable<CleanUpJobTag> queryable)
{
return queryable.Include(cleanUpJobTag => cleanUpJobTag.Tag);
}
}
@@ -0,0 +1,18 @@
using System.Linq;
using Microsoft.EntityFrameworkCore;
using LCU.Library.Internal.DispatcherModels.Models;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Extensions.Queryables;
public static class JobDescriptionQueryable
{
public static IQueryable<Job> FilterJobDescription(this IQueryable<Job> queryable, Filter filter)
{
if (filter?.JobDescription == null)
{
return queryable;
}
return queryable.Where(job => job.Description.Contains(filter.JobDescription));
}
}
@@ -0,0 +1,18 @@
using System.Linq;
using Microsoft.EntityFrameworkCore;
using LCU.Library.Internal.DispatcherModels.Models;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Extensions.Queryables;
public static class JobNameQueryable
{
public static IQueryable<Job> FilterJobName(this IQueryable<Job> queryable, Filter filter)
{
if (filter?.JobName == null)
{
return queryable;
}
return queryable.Where(job => job.Name.Contains(filter.JobName));
}
}
@@ -0,0 +1,18 @@
using System.Linq;
using Microsoft.EntityFrameworkCore;
using LCU.Library.Internal.DispatcherModels.Models;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Extensions.Queryables;
public static class NextRunTimeGreaterThanDateQueryable
{
public static IQueryable<Job> FilterNextRunTimeGreaterThanDate(this IQueryable<Job> queryable, Filter filter)
{
if (filter?.NextRuntimeGreaterThanDate == null)
{
return queryable;
}
return queryable.Where(job => job.NextRunTime >= filter.NextRuntimeGreaterThanDate);
}
}
@@ -0,0 +1,27 @@
using System.Text;
using System.Linq;
using System.Linq.Dynamic.Core;
using LCU.Library.Internal.DispatcherModels.Models;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Extensions.Queryables;
public static class SortableFieldsQueryable
{
public static IQueryable<Job> OrderBySortableFields(this IQueryable<Job> queryable, Filter filter)
{
if (filter?.SortableFields == null || !filter.SortableFields.Any())
{
return queryable;
}
var orderBy = new StringBuilder();
foreach (var field in filter.SortableFields.OrderBy(sortableField => sortableField.Position))
{
var addedComma = orderBy.ToString() == "" ? "" : " ,";
var desc = field.IsDescending ? " desc" : "";
orderBy.Append($"{addedComma}{field.Field}{desc}");
}
return queryable.OrderBy(orderBy.ToString());
}
}
@@ -0,0 +1,47 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Version>2.0.3</Version>
<Description>
1.1.0 - Added EmailRequest and the new ActionType Email.
1.2.0 - Adding JobErrorRecipients
1.3.0 - Adding SftpDynamicFileRequest
1.4.0 - Upgrade to netstandard2.1
2.0.0 - Removed Models and helper classes. DispatcherSharedLib and DispatcherModels should be the used libraries.
2.0.1 - Update NuGet packages
2.0.2 - Update NuGet packages
2.0.3 - Updates to Optimize Queryables
</Description>
<PackageReleaseNotes>
1.1.0 - Added EmailRequest and the new ActionType Email.
1.2.0 - Adding JobErrorRecipients
1.3.0 - Adding SftpDynamicFileRequest
1.4.0 - Upgrade to netstandard2.1
2.0.0 - Removed Models and helper classes. DispatcherSharedLib and DispatcherModels should be the used libraries.
2.0.1 - Update NuGet packages
2.0.2 - Update NuGet packages
2.0.3 - Updates to Optimize Queryables
</PackageReleaseNotes>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LCU.Library.Internal.ApiResponse" Version="3.4.1" />
<PackageReference Include="LCU.Library.Internal.Exceptions" Version="1.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.6.7" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LCU.Library.Internal.DispatcherModels\LCU.Library.Internal.DispatcherModels.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,32 @@
using Microsoft.EntityFrameworkCore;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Persistence;
public class AppDbContext : DbContext
{
public DbSet<Job> Jobs { get; set; }
public DbSet<JobErrorRecipient> JobErrorRecipients { get; set; }
public DbSet<JobTag> JobTags { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<WorkItem> WorkItems { get; set; }
public DbSet<WorkItemExecution> WorkItemExecutions { get; set; }
public DbSet<ExecutionMessage> ExecutionMessages { get; set; }
public DbSet<CleanUpJobSetting> CleanUpJobSettings { get; set; }
public DbSet<CleanUpJobTag> CleanUpJobTags { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Job>().ToTable("Job");
builder.Entity<JobErrorRecipient>().ToTable("JobErrorRecipient");
builder.Entity<JobTag>().ToTable("JobTag");
builder.Entity<Tag>().ToTable("Tag");
builder.Entity<WorkItem>().ToTable("WorkItem");
builder.Entity<WorkItemExecution>().ToTable("WorkItemExecution");
builder.Entity<ExecutionMessage>().ToTable("ExecutionMessage");
builder.Entity<CleanUpJobSetting>().ToTable("CleanUpJobSetting");
builder.Entity<CleanUpJobTag>().ToTable("CleanUpJobTag");
}
}
@@ -0,0 +1,12 @@
using LCU.Api.Internal.DispatcherLib.Persistence;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public abstract class BaseRepository
{
protected readonly AppDbContext _context;
public BaseRepository(AppDbContext context)
{
_context = context;
}
}
@@ -0,0 +1,45 @@
using LCU.Api.Internal.DispatcherLib.Extensions.Queryables;
using LCU.Api.Internal.DispatcherLib.Persistence;
using LCU.Library.Internal.DispatcherModels.Entities;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LCU.Api.Internal.DispatcherLib.Repositories
{
public class CleanUpJobSettingRepository : BaseRepository, ICleanUpJobSettingRepository
{
public CleanUpJobSettingRepository(AppDbContext context) : base(context) { }
public async Task<IEnumerable<CleanUpJobSetting>> ListAsync()
{
return await _context.CleanUpJobSettings.IncludeAll().ToListAsync();
}
public async Task<CleanUpJobSetting> FindByCleanUpJobSettingIdAsync(int cleanUpJobSettingId)
{
return await _context.CleanUpJobSettings.Where(cleanUpJobSetting => cleanUpJobSetting.CleanUpJobSettingId == cleanUpJobSettingId)
.IncludeAll()
.FirstOrDefaultAsync();
}
public async Task<CleanUpJobSetting> AddAsync(CleanUpJobSetting request)
{
var result = await _context.CleanUpJobSettings.AddAsync(request);
return result.Entity;
}
public void Update(CleanUpJobSetting existing)
{
_context.CleanUpJobSettings.Update(existing);
}
public void Remove(CleanUpJobSetting cleanUpJobSetting)
{
_context.CleanUpJobSettings.Remove(cleanUpJobSetting);
}
}
}
@@ -0,0 +1,51 @@
using LCU.Api.Internal.DispatcherLib.Extensions.Queryables;
using LCU.Api.Internal.DispatcherLib.Persistence;
using LCU.Library.Internal.DispatcherModels.Entities;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public class CleanUpJobTagRepository : BaseRepository, ICleanUpJobTagRepository
{
public CleanUpJobTagRepository(AppDbContext context) : base(context) { }
public async Task<IEnumerable<CleanUpJobTag>> ListAsync()
{
return await _context.CleanUpJobTags
.AsNoTracking()
.IncludeAll()
.ToListAsync();
}
public async Task<CleanUpJobTag> FindByCleanUpJobTagIdAsync(int cleanUpJobTagId)
{
return await _context.CleanUpJobTags.Where(cleanUpJobtag => cleanUpJobtag.CleanUpJobTagId == cleanUpJobTagId)
.AsNoTracking()
.IncludeAll()
.FirstOrDefaultAsync();
}
public async Task<IEnumerable<CleanUpJobTag>> FindByCleanUpJobSettingIdAsync(int cleanUpJobSettingId)
{
return await _context.CleanUpJobTags.Where(cleanUpJobtag => cleanUpJobtag.CleanUpJobSettingId == cleanUpJobSettingId)
.AsNoTracking()
.IncludeAll()
.ToListAsync();
}
public async Task<CleanUpJobTag> AddAsync(CleanUpJobTag request)
{
var result = await _context.CleanUpJobTags.AddAsync(request);
return result.Entity;
}
public void Remove(CleanUpJobTag cleanUpJobTag)
{
_context.CleanUpJobTags.Remove(cleanUpJobTag);
}
}
@@ -0,0 +1,23 @@
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
using LCU.Api.Internal.DispatcherLib.Persistence;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public class ExecutionMessageRepository : BaseRepository, IExecutionMessageRepository
{
public ExecutionMessageRepository(AppDbContext context) : base(context) { }
public async Task<ExecutionMessage> FindByIdAsync(int id)
{
return await _context.ExecutionMessages
.AsNoTracking()
.FirstOrDefaultAsync(workItemExecution => workItemExecution.ExecutionMessageId == id);
}
public async Task<ExecutionMessage> AddAsync(ExecutionMessage workItemExecution)
{
var result = await _context.ExecutionMessages.AddAsync(workItemExecution);
return result.Entity;
}
}
@@ -0,0 +1,17 @@
using LCU.Library.Internal.DispatcherModels.Entities;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace LCU.Api.Internal.DispatcherLib.Repositories
{
public interface ICleanUpJobSettingRepository
{
Task<IEnumerable<CleanUpJobSetting>> ListAsync();
Task<CleanUpJobSetting> FindByCleanUpJobSettingIdAsync(int cleanUpJobSettingId);
Task<CleanUpJobSetting> AddAsync(CleanUpJobSetting request);
void Update(CleanUpJobSetting existing);
void Remove(CleanUpJobSetting cleanUpJobSetting);
}
}
@@ -0,0 +1,16 @@
using LCU.Library.Internal.DispatcherModels.Entities;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public interface ICleanUpJobTagRepository
{
Task<IEnumerable<CleanUpJobTag>> ListAsync();
Task<CleanUpJobTag> FindByCleanUpJobTagIdAsync(int cleanUpJobTagId);
Task<IEnumerable<CleanUpJobTag>> FindByCleanUpJobSettingIdAsync(int cleanUpJobSettingId);
Task<CleanUpJobTag> AddAsync(CleanUpJobTag request);
void Remove(CleanUpJobTag cleanUpJobTag);
}
@@ -0,0 +1,9 @@
using System.Threading.Tasks;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public interface IExecutionMessageRepository
{
Task<ExecutionMessage> FindByIdAsync(int id);
Task<ExecutionMessage> AddAsync(ExecutionMessage workItemExecution);
}
@@ -0,0 +1,9 @@
using System.Collections.Generic;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public interface IJobErrorRecipientRepository
{
void AddList(ICollection<JobErrorRecipient> jobErrorRecipients);
void RemoveList(ICollection<JobErrorRecipient> jobErrorRecipients);
}
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using LCU.Library.Internal.DispatcherModels.Entities;
using LCU.Library.Internal.DispatcherModels.Enums;
using LCU.Library.Internal.DispatcherModels.Models;
using LCU.Library.Internal.DispatcherModels.Models.Results;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public interface IJobRepository
{
Task<PagedResult<Job>> FilteredListAsync(Filter filter,
int numberOfWorkItemExecutions,
int numberOfExecutionMessages);
Task<IEnumerable<Job>> ListAsync(int numberOfWorkItemExecutions, int numberOfExecutionMessages);
Task<IEnumerable<Job>> ListInactiveAsync(int numberOfWorkItemExecutions, int numberOfExecutionMessages);
Task<IEnumerable<Job>> ListInactiveExcludeSoftDeletedTrackedAsync(int numberOfWorkItemExecutions, int numberOfExecutionMessages);
Task<IEnumerable<Job>> ListSoftDeletedTrackedAsync(int numberOfWorkItemExecutions, int numberOfExecutionMessages, DateTime cutOffDate);
Task<Job> FindByIdAsync(int id, int numberOfWorkItemExecutions, int numberOfExecutionMessages);
Task<Job> FindByIdExcludingWorkItemsAsync(int id);
Task<Job> FindByWorkItemIdAsync(int workItemId,
int numberOfWorkItemExecutions,
int numberOfExecutionMessages);
Task<Job> FindByWorkItemIdExcludingWorkItemsAsync(int workItemId);
Task<Job> FindByWorkItemIdExcludingWorkItemsIncludeErrorRecipientsAsync(int workItemId);
Task<IEnumerable<Job>> FindJobsPastDateByStatuses(DateTime date,
int numberOfWorkItemExecutions,
int numberOfExecutionMessages,
List<JobStatus> jobStatuses);
Task<IEnumerable<Job>> FindJobsReadyToBeScheduled(DateTime date);
Task<Job> AddAsync(Job job);
Task<Job> Update(Job job);
void Remove(Job job);
}
@@ -0,0 +1,13 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public interface IJobTagRepository
{
Task<IEnumerable<JobTag>> ListAsync();
Task<JobTag> FindByIdAsync(int jobTagId);
Task<IEnumerable<JobTag>> FindByTagIdAsync(int tagId);
Task<JobTag> AddAsync(JobTag jobTag);
void Remove(JobTag jobTag);
}
@@ -0,0 +1,13 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public interface ITagRepository
{
Task<IEnumerable<Tag>> ListAsync();
Task<Tag> FindByIdAsync(int tagId);
Task<Tag> AddAsync(Tag tag);
void Update(Tag tag);
void Remove(Tag tag);
}
@@ -0,0 +1,8 @@
using System.Threading.Tasks;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public interface IUnitOfWork
{
Task CompleteAsync();
void Complete();
}
@@ -0,0 +1,14 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public interface IWorkItemExecutionRepository
{
Task<IEnumerable<WorkItemExecution>> ListAsync();
Task<WorkItemExecution> FindByIdAsync(int id);
Task<WorkItemExecution> AddAsync(WorkItemExecution workItemExecution);
void Update(WorkItemExecution workItemExecution);
Task<IEnumerable<WorkItemExecution>> FindUnFinishedWorkItemExecutions(int workItemId);
Task<IEnumerable<WorkItemExecution>> FindAllByWorkItemId(int workItemId);
}
@@ -0,0 +1,20 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public interface IWorkItemRepository
{
Task<IEnumerable<WorkItem>> ListAsync();
Task<WorkItem> FindByIdAsync(int id);
Task<IEnumerable<WorkItem>> FindByJobIdAsync(int jobId);
Task<IEnumerable<WorkItem>> FindByJobIdWithExecutionsAsync(int jobId, int numberOfWorkItemExecutions, int numberOfExecutionMessages);
Task<WorkItem> GetFirstOrDefaultWorkItemByJobId(int jobId);
Task<WorkItem> GetNextWorkItemByJobId(int jobId, int currentWorkItemOrder);
Task<WorkItem> GetTrackedWorkItem(int workItemId);
Task<WorkItem> AddAsync(WorkItem workItem);
void AddList(IEnumerable<WorkItem> workItems);
void Update(WorkItem workItem);
void RemoveList(IEnumerable<WorkItem> workItems);
}
@@ -0,0 +1,19 @@
using System.Collections.Generic;
using LCU.Api.Internal.DispatcherLib.Persistence;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public class JobErrorRecipientRepository : BaseRepository, IJobErrorRecipientRepository
{
public JobErrorRecipientRepository(AppDbContext context) : base(context) { }
public void AddList(ICollection<JobErrorRecipient> jobErrorRecipients)
{
_context.JobErrorRecipients.AddRangeAsync(jobErrorRecipients);
}
public void RemoveList(ICollection<JobErrorRecipient> jobErrorRecipients)
{
_context.JobErrorRecipients.RemoveRange(jobErrorRecipients);
}
}
@@ -0,0 +1,159 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using LCU.Library.Internal.DispatcherModels.Models;
using LCU.Library.Internal.DispatcherModels.Entities;
using LCU.Api.Internal.DispatcherLib.Persistence;
using LCU.Api.Internal.DispatcherLib.Extensions.Queryables;
using LCU.Api.Internal.DispatcherLib.Extensions.Enumerables;
using LCU.Library.Internal.DispatcherModels.Models.Results;
using LCU.Library.Internal.DispatcherModels.Enums;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public class JobRepository : BaseRepository, IJobRepository
{
public JobRepository(AppDbContext context) : base(context) { }
public async Task<PagedResult<Job>> FilteredListAsync(Filter filter,
int numberOfWorkItemExecutions,
int numberOfExecutionMessages)
{
var results = new PagedResult<Job>();
var skip = (filter.Page - 1) * filter.Limit;
results.Total = await _context.Jobs.Where(job => job.SoftDeleteDate == null)
.IncludeAll(numberOfWorkItemExecutions, numberOfExecutionMessages)
.FilterJobName(filter)
.FilterJobDescription(filter)
.FilterNextRunTimeGreaterThanDate(filter)
.FilterOnTagId(filter)
.FilterByStatusType(filter)
.AsNoTracking()
.CountAsync();
//Queryable
var jobs = await _context.Jobs.Where(job => job.SoftDeleteDate == null)
.IncludeAll(numberOfWorkItemExecutions, numberOfExecutionMessages)
.FilterJobName(filter)
.FilterJobDescription(filter)
.FilterNextRunTimeGreaterThanDate(filter)
.FilterOnTagId(filter)
.FilterByStatusType(filter)
.OrderBySortableFields(filter)
.AsNoTracking()
.ToListAsync();
results.Items = jobs.Skip(skip).Take(filter.Limit);
return results;
}
public async Task<IEnumerable<Job>> ListAsync(int numberOfWorkItemExecutions, int numberOfExecutionMessages)
{
return await _context.Jobs.IncludeAll(numberOfWorkItemExecutions, numberOfExecutionMessages)
.AsNoTracking()
.ToListAsync();
}
public async Task<IEnumerable<Job>> ListInactiveAsync(int numberOfWorkItemExecutions, int numberOfExecutionMessages)
{
return await _context.Jobs.Where(job => string.IsNullOrWhiteSpace(job.CronSchedule) && job.NextRunTime == null)
.IncludeAll(numberOfWorkItemExecutions, numberOfExecutionMessages)
.AsNoTracking()
.ToListAsync();
}
public async Task<IEnumerable<Job>> ListInactiveExcludeSoftDeletedTrackedAsync(int numberOfWorkItemExecutions, int numberOfExecutionMessages)
{
return await _context.Jobs.Where(job => string.IsNullOrWhiteSpace(job.CronSchedule) && job.NextRunTime == null && job.SoftDeleteDate == null)
.IncludeAll(numberOfWorkItemExecutions, numberOfExecutionMessages)
.ToListAsync();
}
public async Task<IEnumerable<Job>> ListSoftDeletedTrackedAsync(int numberOfWorkItemExecutions, int numberOfExecutionMessages, DateTime cutOffDate)
{
return await _context.Jobs.Where(job => job.SoftDeleteDate != null && cutOffDate > job.SoftDeleteDate)
.IncludeAll(numberOfWorkItemExecutions, numberOfExecutionMessages)
.ToListAsync();
}
public async Task<Job> FindByIdAsync(int id, int numberOfWorkItemExecutions, int numberOfExecutionMessages)
{
return await _context.Jobs.Where(job => job.JobId == id)
.IncludeAll(numberOfWorkItemExecutions, numberOfExecutionMessages)
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<Job> FindByIdExcludingWorkItemsAsync(int id)
{
return await _context.Jobs.Where(job => job.JobId == id)
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<Job> FindByWorkItemIdAsync(int workItemId, int numberOfWorkItemExecutions, int numberOfExecutionMessages)
{
return await _context.Jobs.Where(job => job.WorkItems.Any(workItem => workItem.WorkItemId == workItemId))
.IncludeAll(numberOfWorkItemExecutions, numberOfExecutionMessages)
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<Job> FindByWorkItemIdExcludingWorkItemsAsync(int workItemId)
{
return await _context.Jobs.Where(job => job.WorkItems.Any(workItem => workItem.WorkItemId == workItemId))
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<Job> FindByWorkItemIdExcludingWorkItemsIncludeErrorRecipientsAsync(int workItemId)
{
return await _context.Jobs.Where(job => job.WorkItems.Any(workItem => workItem.WorkItemId == workItemId))
.IncludeErrorRecipients()
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<IEnumerable<Job>> FindJobsPastDateByStatuses(DateTime date,
int numberOfWorkItemExecutions,
int numberOfExecutionMessages,
List<JobStatus> jobStatuses)
{
return await _context.Jobs.Where(job => date > job.NextRunTime && (jobStatuses.Contains(job.JobStatus) || job.JobStatus == JobStatus.Failed))
.IncludeAll(numberOfWorkItemExecutions, numberOfExecutionMessages)
.AsNoTracking()
.ToListAsync();
}
public async Task<IEnumerable<Job>> FindJobsReadyToBeScheduled(DateTime date)
{
var jobs = await _context.Jobs.Where(job => (job.JobStatus == JobStatus.ReadyToSchedule && job.NextRunTime < date))
.AsNoTracking()
.ToListAsync();
return jobs;
}
public async Task<Job> AddAsync(Job job)
{
var result = await _context.Jobs.AddAsync(job);
return result.Entity;
}
public async Task<Job> Update(Job job)
{
var trackedJob = await _context.Jobs
.FirstAsync(j => j.JobId == job.JobId);
_context.Entry(trackedJob).CurrentValues.SetValues(job);
return trackedJob;
}
public void Remove(Job job)
{
_context.Jobs.Remove(job);
}
}
@@ -0,0 +1,46 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using LCU.Api.Internal.DispatcherLib.Persistence;
using LCU.Api.Internal.DispatcherLib.Extensions.Queryables;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public class JobTagRepository : BaseRepository, IJobTagRepository
{
public JobTagRepository(AppDbContext context) : base(context) { }
public async Task<IEnumerable<JobTag>> ListAsync()
{
return await _context.JobTags.IncludeAll()
.AsNoTracking()
.ToListAsync();
}
public async Task<JobTag> FindByIdAsync(int jobTagId)
{
return await _context.JobTags.Where(jobTag => jobTag.JobTagId == jobTagId)
.IncludeAll()
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<IEnumerable<JobTag>> FindByTagIdAsync(int tagId)
{
return await _context.JobTags.Where(tag => tag.TagId == tagId)
.AsNoTracking()
.ToListAsync();
}
public async Task<JobTag> AddAsync(JobTag jobTag)
{
var result = await _context.JobTags.AddAsync(jobTag);
return result.Entity;
}
public void Remove(JobTag jobTag)
{
_context.JobTags.Remove(jobTag);
}
}
@@ -0,0 +1,40 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using LCU.Api.Internal.DispatcherLib.Persistence;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public class TagRepository : BaseRepository, ITagRepository
{
public TagRepository(AppDbContext context) : base(context) { }
public async Task<IEnumerable<Tag>> ListAsync()
{
return await _context.Tags.AsNoTracking().ToListAsync();
}
public async Task<Tag> FindByIdAsync(int tagId)
{
return await _context.Tags.Where(tag => tag.TagId == tagId)
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<Tag> AddAsync(Tag tag)
{
var result = await _context.Tags.AddAsync(tag);
return result.Entity;
}
public void Update(Tag tag)
{
_context.Tags.Update(tag);
}
public void Remove(Tag tag)
{
_context.Tags.Remove(tag);
}
}
@@ -0,0 +1,23 @@
using LCU.Api.Internal.DispatcherLib.Persistence;
using System.Threading.Tasks;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public class UnitOfWork : IUnitOfWork
{
private readonly AppDbContext _context;
public UnitOfWork(AppDbContext context)
{
_context = context;
}
public async Task CompleteAsync()
{
await _context.SaveChangesAsync();
}
public void Complete()
{
_context.SaveChanges();
}
}
@@ -0,0 +1,54 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using LCU.Api.Internal.DispatcherLib.Persistence;
using LCU.Library.Internal.DispatcherModels.Entities;
using LCU.Api.Internal.DispatcherLib.Extensions.Queryables;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public class WorkItemExecutionRepository : BaseRepository, IWorkItemExecutionRepository
{
public WorkItemExecutionRepository(AppDbContext context) : base(context) { }
public async Task<IEnumerable<WorkItemExecution>> ListAsync()
{
return await _context.WorkItemExecutions.AsNoTracking().ToListAsync();
}
public async Task<WorkItemExecution> FindByIdAsync(int id)
{
return await _context.WorkItemExecutions
.AsNoTracking()
.FirstOrDefaultAsync(workItemExecution => workItemExecution.WorkItemExecutionId == id);
}
public async Task<WorkItemExecution> AddAsync(WorkItemExecution workItemExecution)
{
var result = await _context.WorkItemExecutions.AddAsync(workItemExecution);
return result.Entity;
}
public void Update(WorkItemExecution workItem)
{
_context.WorkItemExecutions.Update(workItem);
}
public async Task<IEnumerable<WorkItemExecution>> FindUnFinishedWorkItemExecutions(int workItemId)
{
var result = await _context.WorkItemExecutions.Where(workItemExecution => workItemExecution.StartedTimestamp == null || workItemExecution.CompletedTimestamp == null)
.Where(workItemExecution => workItemExecution.WorkItemId == workItemId).AsNoTracking().ToListAsync();
return result;
}
public async Task<IEnumerable<WorkItemExecution>> FindAllByWorkItemId(int workItemId)
{
var result = await _context.WorkItemExecutions.Where(workItemExecution => workItemExecution.WorkItemId == workItemId)
.AsNoTracking()
.IncludeAll()
.ToListAsync();
return result;
}
}
@@ -0,0 +1,93 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using LCU.Api.Internal.DispatcherLib.Persistence;
using LCU.Api.Internal.DispatcherLib.Extensions.Queryables;
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.Api.Internal.DispatcherLib.Repositories;
public class WorkItemRepository : BaseRepository, IWorkItemRepository
{
public WorkItemRepository(AppDbContext context) : base(context) { }
public async Task<IEnumerable<WorkItem>> ListByJobIdAsync(int jobId)
{
return await _context.WorkItems.Where(wi => wi.JobId == jobId)
.IncludeAll()
.AsNoTracking()
.ToListAsync();
}
public async Task<IEnumerable<WorkItem>> ListAsync()
{
return await _context.WorkItems.IncludeAll()
.AsNoTracking()
.ToListAsync();
}
public async Task<WorkItem> FindByIdAsync(int id)
{
return await _context.WorkItems.Where(workItem => workItem.WorkItemId == id)
.IncludeAll()
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<IEnumerable<WorkItem>> FindByJobIdAsync(int jobId)
{
return await _context.WorkItems.Where(workItem => workItem.JobId == jobId)
.AsNoTracking()
.ToListAsync();
}
public async Task<IEnumerable<WorkItem>> FindByJobIdWithExecutionsAsync(int jobId, int numberOfWorkItemExecutions, int numberOfExecutionMessages)
{
return await _context.WorkItems.Where(workItem => workItem.JobId == jobId)
.IncludeAll(numberOfWorkItemExecutions, numberOfExecutionMessages)
.AsNoTracking()
.ToListAsync();
}
public async Task<WorkItem> GetFirstOrDefaultWorkItemByJobId(int jobId)
{
return await _context.WorkItems.Where(workItem => workItem.JobId == jobId)
.OrderBy(wi => wi.Order)
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<WorkItem> GetNextWorkItemByJobId(int jobId, int currentWorkItemOrder)
{
return await _context.WorkItems.Where(workItem => workItem.JobId == jobId && workItem.Order > currentWorkItemOrder)
.OrderBy(wi => wi.Order)
.AsNoTracking()
.FirstOrDefaultAsync();
}
public async Task<WorkItem> GetTrackedWorkItem(int workItemId)
{
return await _context.WorkItems.FirstAsync(w => w.WorkItemId == workItemId);
}
public async Task<WorkItem> AddAsync(WorkItem workItem)
{
var result = await _context.WorkItems.AddAsync(workItem);
return result.Entity;
}
public void Update(WorkItem workItem)
{
_context.WorkItems.Update(workItem);
}
public void AddList(IEnumerable<WorkItem> workItems)
{
_context.WorkItems.AddRange(workItems);
}
public void RemoveList(IEnumerable<WorkItem> workItems)
{
_context.WorkItems.RemoveRange(workItems);
}
}