Merge pull request #6053 from sbwalker/dev

change JobTask to SiteTask
This commit is contained in:
Shaun Walker
2026-02-19 10:47:49 -05:00
committed by GitHub
19 changed files with 197 additions and 160 deletions

View File

@@ -41,7 +41,6 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddScoped<ILogService, LogService>(); services.AddScoped<ILogService, LogService>();
services.AddScoped<IJobService, JobService>(); services.AddScoped<IJobService, JobService>();
services.AddScoped<IJobLogService, JobLogService>(); services.AddScoped<IJobLogService, JobLogService>();
services.AddScoped<IJobTaskService, JobTaskService>();
services.AddScoped<INotificationService, Oqtane.Services.NotificationService>(); services.AddScoped<INotificationService, Oqtane.Services.NotificationService>();
services.AddScoped<IFolderService, FolderService>(); services.AddScoped<IFolderService, FolderService>();
services.AddScoped<IFileService, FileService>(); services.AddScoped<IFileService, FileService>();
@@ -60,6 +59,7 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddScoped<IMigrationHistoryService, MigrationHistoryService>(); services.AddScoped<IMigrationHistoryService, MigrationHistoryService>();
services.AddScoped<ISiteGroupService, SiteGroupService>(); services.AddScoped<ISiteGroupService, SiteGroupService>();
services.AddScoped<ISiteGroupMemberService, SiteGroupMemberService>(); services.AddScoped<ISiteGroupMemberService, SiteGroupMemberService>();
services.AddScoped<ISiteTaskService, SiteTaskService>();
services.AddScoped<IOutputCacheService, OutputCacheService>(); services.AddScoped<IOutputCacheService, OutputCacheService>();
// providers // providers

View File

@@ -1,7 +1,7 @@
@namespace Oqtane.Modules.Admin.GlobalReplace @namespace Oqtane.Modules.Admin.GlobalReplace
@using System.Text.Json @using System.Text.Json
@inherits ModuleBase @inherits ModuleBase
@inject IJobTaskService JobTaskService @inject ISiteTaskService SiteTaskService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer @inject IStringLocalizer<SharedResources> SharedLocalizer
@@ -97,8 +97,8 @@
Content = bool.Parse(_content) Content = bool.Parse(_content)
}; };
var jobTask = new JobTask(PageState.Site.SiteId, "Global Replace", "Oqtane.Infrastructure.GlobalReplaceTask, Oqtane.Server", JsonSerializer.Serialize(replace)); var siteTask = new SiteTask(PageState.Site.SiteId, "Global Replace", "Oqtane.Infrastructure.GlobalReplaceTask, Oqtane.Server", JsonSerializer.Serialize(replace));
await JobTaskService.AddJobTaskAsync(jobTask); await SiteTaskService.AddSiteTaskAsync(siteTask);
AddModuleMessage(Localizer["Success.Save"], MessageType.Success); AddModuleMessage(Localizer["Success.Save"], MessageType.Success);
} }

View File

@@ -1,7 +1,7 @@
@namespace Oqtane.Modules.Admin.Users @namespace Oqtane.Modules.Admin.Users
@inherits ModuleBase @inherits ModuleBase
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IJobTaskService JobTaskService @inject ISiteTaskService SiteTaskService
@inject IStringLocalizer<Users> Localizer @inject IStringLocalizer<Users> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer @inject IStringLocalizer<SharedResources> SharedLocalizer
@@ -43,8 +43,8 @@
var fileid = _filemanager.GetFileId(); var fileid = _filemanager.GetFileId();
if (fileid != -1) if (fileid != -1)
{ {
var jobTask = new JobTask(PageState.Site.SiteId, "Import Users", "Oqtane.Infrastructure.ImportUsersTask, Oqtane.Server", $"{fileid}:{_notify}"); var siteTask = new SiteTask(PageState.Site.SiteId, "Import Users", "Oqtane.Infrastructure.ImportUsersTask, Oqtane.Server", $"{fileid}:{_notify}");
await JobTaskService.AddJobTaskAsync(jobTask); await SiteTaskService.AddSiteTaskAsync(siteTask);
AddModuleMessage(Localizer["Message.Import.Success"], MessageType.Success); AddModuleMessage(Localizer["Message.Import.Success"], MessageType.Success);
} }
else else

View File

@@ -1,46 +0,0 @@
using Oqtane.Models;
using System.Threading.Tasks;
using System.Net.Http;
using Oqtane.Documentation;
using Oqtane.Shared;
namespace Oqtane.Services
{
/// <summary>
/// Service to manage tasks (<see cref="JobTask"/>)
/// </summary>
public interface IJobTaskService
{
/// <summary>
/// Return a specific task
/// </summary>
/// <param name="jobTaskId"></param>
/// <returns></returns>
Task<JobTask> GetJobTaskAsync(int jobTaskId);
/// <summary>
/// Adds a new task
/// </summary>
/// <param name="jobTask"></param>
/// <returns></returns>
Task<JobTask> AddJobTaskAsync(JobTask jobTask);
}
[PrivateApi("Don't show in the documentation, as everything should use the Interface")]
public class JobTaskService : ServiceBase, IJobTaskService
{
public JobTaskService(HttpClient http, SiteState siteState) : base(http, siteState) { }
private string Apiurl => CreateApiUrl("JobTask");
public async Task<JobTask> GetJobTaskAsync(int jobTaskId)
{
return await GetJsonAsync<JobTask>($"{Apiurl}/{jobTaskId}");
}
public async Task<JobTask> AddJobTaskAsync(JobTask jobTask)
{
return await PostJsonAsync<JobTask>(Apiurl, jobTask);
}
}
}

View File

@@ -0,0 +1,46 @@
using Oqtane.Models;
using System.Threading.Tasks;
using System.Net.Http;
using Oqtane.Documentation;
using Oqtane.Shared;
namespace Oqtane.Services
{
/// <summary>
/// Service to manage tasks (<see cref="SiteTask"/>)
/// </summary>
public interface ISiteTaskService
{
/// <summary>
/// Return a specific task
/// </summary>
/// <param name="siteTaskId"></param>
/// <returns></returns>
Task<SiteTask> GetSiteTaskAsync(int siteTaskId);
/// <summary>
/// Adds a new task
/// </summary>
/// <param name="siteTask"></param>
/// <returns></returns>
Task<SiteTask> AddSiteTaskAsync(SiteTask siteTask);
}
[PrivateApi("Don't show in the documentation, as everything should use the Interface")]
public class SiteTaskService : ServiceBase, ISiteTaskService
{
public SiteTaskService(HttpClient http, SiteState siteState) : base(http, siteState) { }
private string Apiurl => CreateApiUrl("SiteTask");
public async Task<SiteTask> GetSiteTaskAsync(int siteTaskId)
{
return await GetJsonAsync<SiteTask>($"{Apiurl}/{siteTaskId}");
}
public async Task<SiteTask> AddSiteTaskAsync(SiteTask siteTask)
{
return await PostJsonAsync<SiteTask>(Apiurl, siteTask);
}
}
}

View File

@@ -10,15 +10,15 @@ using Oqtane.Shared;
namespace Oqtane.Controllers namespace Oqtane.Controllers
{ {
[Route(ControllerRoutes.ApiRoute)] [Route(ControllerRoutes.ApiRoute)]
public class JobTaskController : Controller public class SiteTaskController : Controller
{ {
private readonly IJobTaskRepository _jobTasks; private readonly ISiteTaskRepository _siteTasks;
private readonly ILogManager _logger; private readonly ILogManager _logger;
private readonly Alias _alias; private readonly Alias _alias;
public JobTaskController(IJobTaskRepository jobTasks, ILogManager logger, ITenantManager tenantManager) public SiteTaskController(ISiteTaskRepository siteTasks, ILogManager logger, ITenantManager tenantManager)
{ {
_jobTasks = jobTasks; _siteTasks = siteTasks;
_logger = logger; _logger = logger;
_alias = tenantManager.GetAlias(); _alias = tenantManager.GetAlias();
} }
@@ -26,12 +26,12 @@ namespace Oqtane.Controllers
// GET api/<controller>/5 // GET api/<controller>/5
[HttpGet("{id}")] [HttpGet("{id}")]
[Authorize(Roles = RoleNames.Admin)] [Authorize(Roles = RoleNames.Admin)]
public JobTask Get(int id) public SiteTask Get(int id)
{ {
var jobTask = _jobTasks.GetJobTask(id); var siteTask = _siteTasks.GetSiteTask(id);
if (jobTask.SiteId == _alias.SiteId) if (siteTask.SiteId == _alias.SiteId)
{ {
return jobTask; return siteTask;
} }
else else
{ {
@@ -43,21 +43,21 @@ namespace Oqtane.Controllers
// POST api/<controller> // POST api/<controller>
[HttpPost] [HttpPost]
[Authorize(Roles = RoleNames.Admin)] [Authorize(Roles = RoleNames.Admin)]
public JobTask Post([FromBody] JobTask jobTask) public SiteTask Post([FromBody] SiteTask siteTask)
{ {
if (ModelState.IsValid && jobTask.SiteId == _alias.SiteId) if (ModelState.IsValid && siteTask.SiteId == _alias.SiteId)
{ {
jobTask.IsCompleted = false; siteTask.IsCompleted = false;
jobTask = _jobTasks.AddJobTask(jobTask); siteTask = _siteTasks.AddSiteTask(siteTask);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Job Task Added {JobTask}", jobTask); _logger.Log(LogLevel.Information, this, LogFunction.Create, "Site Task Added {SiteTask}", siteTask);
} }
else else
{ {
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Job Task Post Attempt {JobTask}", jobTask); _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Site Task Post Attempt {SiteTask}", siteTask);
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
jobTask = null; siteTask = null;
} }
return jobTask; return siteTask;
} }
} }
} }

View File

@@ -214,7 +214,6 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddScoped<ILogService, LogService>(); services.AddScoped<ILogService, LogService>();
services.AddScoped<IJobService, JobService>(); services.AddScoped<IJobService, JobService>();
services.AddScoped<IJobLogService, JobLogService>(); services.AddScoped<IJobLogService, JobLogService>();
services.AddScoped<IJobTaskService, JobTaskService>();
services.AddScoped<INotificationService, Oqtane.Services.NotificationService>(); services.AddScoped<INotificationService, Oqtane.Services.NotificationService>();
services.AddScoped<IFolderService, FolderService>(); services.AddScoped<IFolderService, FolderService>();
services.AddScoped<IFileService, FileService>(); services.AddScoped<IFileService, FileService>();
@@ -236,6 +235,7 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddScoped<IMigrationHistoryService, MigrationHistoryService>(); services.AddScoped<IMigrationHistoryService, MigrationHistoryService>();
services.AddScoped<ISiteGroupService, SiteGroupService>(); services.AddScoped<ISiteGroupService, SiteGroupService>();
services.AddScoped<ISiteGroupMemberService, SiteGroupMemberService>(); services.AddScoped<ISiteGroupMemberService, SiteGroupMemberService>();
services.AddScoped<ISiteTaskService, SiteTaskService>();
// providers // providers
services.AddScoped<ITextEditor, Oqtane.Modules.Controls.QuillJSTextEditor>(); services.AddScoped<ITextEditor, Oqtane.Modules.Controls.QuillJSTextEditor>();
@@ -275,7 +275,6 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddTransient<ILogRepository, LogRepository>(); services.AddTransient<ILogRepository, LogRepository>();
services.AddTransient<IJobRepository, JobRepository>(); services.AddTransient<IJobRepository, JobRepository>();
services.AddTransient<IJobLogRepository, JobLogRepository>(); services.AddTransient<IJobLogRepository, JobLogRepository>();
services.AddTransient<IJobTaskRepository, JobTaskRepository>();
services.AddTransient<INotificationRepository, NotificationRepository>(); services.AddTransient<INotificationRepository, NotificationRepository>();
services.AddTransient<IFolderRepository, FolderRepository>(); services.AddTransient<IFolderRepository, FolderRepository>();
services.AddTransient<IFileRepository, FileRepository>(); services.AddTransient<IFileRepository, FileRepository>();
@@ -288,6 +287,7 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddTransient<IMigrationHistoryRepository, MigrationHistoryRepository>(); services.AddTransient<IMigrationHistoryRepository, MigrationHistoryRepository>();
services.AddTransient<ISiteGroupRepository, SiteGroupRepository>(); services.AddTransient<ISiteGroupRepository, SiteGroupRepository>();
services.AddTransient<ISiteGroupMemberRepository, SiteGroupMemberRepository>(); services.AddTransient<ISiteGroupMemberRepository, SiteGroupMemberRepository>();
services.AddTransient<ISiteTaskRepository, SiteTaskRepository>();
// managers // managers
services.AddTransient<IDBContextDependencies, DBContextDependencies>(); services.AddTransient<IDBContextDependencies, DBContextDependencies>();

View File

@@ -4,7 +4,7 @@ using Oqtane.Models;
namespace Oqtane.Infrastructure namespace Oqtane.Infrastructure
{ {
public interface IJobTask public interface ISiteTask
{ {
string ExecuteTask(IServiceProvider provider, Site site, string parameters); string ExecuteTask(IServiceProvider provider, Site site, string parameters);

View File

@@ -33,6 +33,7 @@ namespace Oqtane.Infrastructure
var visitorRepository = provider.GetRequiredService<IVisitorRepository>(); var visitorRepository = provider.GetRequiredService<IVisitorRepository>();
var notificationRepository = provider.GetRequiredService<INotificationRepository>(); var notificationRepository = provider.GetRequiredService<INotificationRepository>();
var urlMappingRepository = provider.GetRequiredService<IUrlMappingRepository>(); var urlMappingRepository = provider.GetRequiredService<IUrlMappingRepository>();
var siteTaskRepository = provider.GetRequiredService<ISiteTaskRepository>();
// iterate through sites for current tenant // iterate through sites for current tenant
List<Site> sites = siteRepository.GetSites().ToList(); List<Site> sites = siteRepository.GetSites().ToList();
@@ -94,6 +95,18 @@ namespace Oqtane.Infrastructure
{ {
log += $"Error Purging Broken Urls - {ex.Message}<br />"; log += $"Error Purging Broken Urls - {ex.Message}<br />";
} }
// purge completed site tasks
retention = 30; // 30 day default
try
{
count = siteTaskRepository.DeleteSiteTasks(site.SiteId, retention);
log += count.ToString() + " Completed Tasks Purged<br />";
}
catch (Exception ex)
{
log += $"Error Purging Completed Site Tasks - {ex.Message}<br />";
}
} }
return log; return log;

View File

@@ -7,11 +7,11 @@ using Oqtane.Repository;
namespace Oqtane.Infrastructure namespace Oqtane.Infrastructure
{ {
public class TaskJob : HostedServiceBase public class SiteTaskJob : HostedServiceBase
{ {
public TaskJob(IServiceScopeFactory serviceScopeFactory) : base(serviceScopeFactory) public SiteTaskJob(IServiceScopeFactory serviceScopeFactory) : base(serviceScopeFactory)
{ {
Name = "Task Job"; Name = "Site Task Job";
Frequency = "m"; // run every minute Frequency = "m"; // run every minute
Interval = 1; Interval = 1;
IsEnabled = true; IsEnabled = true;
@@ -33,8 +33,8 @@ namespace Oqtane.Infrastructure
log += $"Processing Site: {site.Name}<br />"; log += $"Processing Site: {site.Name}<br />";
// get incomplete tasks for site // get incomplete tasks for site
var jobTaskRepository = provider.GetRequiredService<IJobTaskRepository>(); var siteTaskRepository = provider.GetRequiredService<ISiteTaskRepository>();
var tasks = jobTaskRepository.GetJobTasks(site.SiteId).ToList(); var tasks = siteTaskRepository.GetSiteTasks(site.SiteId).ToList();
if (tasks != null && tasks.Any()) if (tasks != null && tasks.Any())
{ {
foreach (var task in tasks) foreach (var task in tasks)
@@ -42,15 +42,15 @@ namespace Oqtane.Infrastructure
log += $"Executing Task: {task.Name}<br />"; log += $"Executing Task: {task.Name}<br />";
Type taskType = Type.GetType(task.Type); Type taskType = Type.GetType(task.Type);
if (taskType != null && taskType.GetInterface(nameof(IJobTask)) != null) if (taskType != null && taskType.GetInterface(nameof(ISiteTask)) != null)
{ {
try try
{ {
tenantManager.SetAlias(tenant.TenantId, site.SiteId); tenantManager.SetAlias(tenant.TenantId, site.SiteId);
var taskObject = ActivatorUtilities.CreateInstance(provider, taskType); var taskObject = ActivatorUtilities.CreateInstance(provider, taskType);
var taskLog = ((IJobTask)taskObject).ExecuteTask(provider, site, task.Parameters); var taskLog = ((ISiteTask)taskObject).ExecuteTask(provider, site, task.Parameters);
taskLog += await ((IJobTask)taskObject).ExecuteTaskAsync(provider, site, task.Parameters); taskLog += await ((ISiteTask)taskObject).ExecuteTaskAsync(provider, site, task.Parameters);
task.Status = taskLog; task.Status = taskLog;
} }
@@ -66,7 +66,7 @@ namespace Oqtane.Infrastructure
// update task // update task
task.IsCompleted = true; task.IsCompleted = true;
jobTaskRepository.UpdateJobTask(task); siteTaskRepository.UpdateSiteTask(task);
log += task.Status + "<br />"; log += task.Status + "<br />";
} }

View File

@@ -8,7 +8,7 @@ using Oqtane.Repository;
namespace Oqtane.Infrastructure namespace Oqtane.Infrastructure
{ {
public class GlobalReplaceTask : JobTaskBase public class GlobalReplaceTask : SiteTaskBase
{ {
public override string ExecuteTask(IServiceProvider provider, Site site, string parameters) public override string ExecuteTask(IServiceProvider provider, Site site, string parameters)
{ {

View File

@@ -7,7 +7,7 @@ using Oqtane.Repository;
namespace Oqtane.Infrastructure namespace Oqtane.Infrastructure
{ {
public class ImportUsersTask : JobTaskBase public class ImportUsersTask : SiteTaskBase
{ {
public override async Task<string> ExecuteTaskAsync(IServiceProvider provider, Site site, string parameters) public override async Task<string> ExecuteTaskAsync(IServiceProvider provider, Site site, string parameters)
{ {

View File

@@ -4,7 +4,7 @@ using Oqtane.Models;
namespace Oqtane.Infrastructure namespace Oqtane.Infrastructure
{ {
public class JobTaskBase : IJobTask public class SiteTaskBase : ISiteTask
{ {
public virtual string ExecuteTask(IServiceProvider provider, Site site, string parameters) public virtual string ExecuteTask(IServiceProvider provider, Site site, string parameters)
{ {

View File

@@ -9,22 +9,22 @@ using Oqtane.Interfaces;
namespace Oqtane.Migrations.EntityBuilders namespace Oqtane.Migrations.EntityBuilders
{ {
public class JobTaskEntityBuilder : AuditableBaseEntityBuilder<JobTaskEntityBuilder> public class SiteTaskEntityBuilder : AuditableBaseEntityBuilder<SiteTaskEntityBuilder>
{ {
private const string _entityTableName = "JobTask"; private const string _entityTableName = "SiteTask";
private readonly PrimaryKey<JobTaskEntityBuilder> _primaryKey = new("PK_JobTask", x => x.JobTaskId); private readonly PrimaryKey<SiteTaskEntityBuilder> _primaryKey = new("PK_SiteTask", x => x.SiteTaskId);
private readonly ForeignKey<JobTaskEntityBuilder> _siteForeignKey = new("FK_JobTask_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade); private readonly ForeignKey<SiteTaskEntityBuilder> _siteForeignKey = new("FK_SiteTask_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
public JobTaskEntityBuilder(MigrationBuilder migrationBuilder, IDatabase database) : base(migrationBuilder, database) public SiteTaskEntityBuilder(MigrationBuilder migrationBuilder, IDatabase database) : base(migrationBuilder, database)
{ {
EntityTableName = _entityTableName; EntityTableName = _entityTableName;
PrimaryKey = _primaryKey; PrimaryKey = _primaryKey;
ForeignKeys.Add(_siteForeignKey); ForeignKeys.Add(_siteForeignKey);
} }
protected override JobTaskEntityBuilder BuildTable(ColumnsBuilder table) protected override SiteTaskEntityBuilder BuildTable(ColumnsBuilder table)
{ {
JobTaskId = AddAutoIncrementColumn(table,"JobTaskId"); SiteTaskId = AddAutoIncrementColumn(table,"SiteTaskId");
SiteId = AddIntegerColumn(table,"SiteId"); SiteId = AddIntegerColumn(table,"SiteId");
Name = AddStringColumn(table, "Name", 200); Name = AddStringColumn(table, "Name", 200);
Type = AddStringColumn(table, "Type", 200); Type = AddStringColumn(table, "Type", 200);
@@ -37,7 +37,7 @@ namespace Oqtane.Migrations.EntityBuilders
return this; return this;
} }
public OperationBuilder<AddColumnOperation> JobTaskId { get; private set; } public OperationBuilder<AddColumnOperation> SiteTaskId { get; private set; }
public OperationBuilder<AddColumnOperation> SiteId { get; private set; } public OperationBuilder<AddColumnOperation> SiteId { get; private set; }

View File

@@ -8,16 +8,16 @@ namespace Oqtane.Migrations.Tenant
{ {
[DbContext(typeof(TenantDBContext))] [DbContext(typeof(TenantDBContext))]
[Migration("Tenant.10.01.00.04")] [Migration("Tenant.10.01.00.04")]
public class AddJobTasks : MultiDatabaseMigration public class AddSiteTasks : MultiDatabaseMigration
{ {
public AddJobTasks(IDatabase database) : base(database) public AddSiteTasks(IDatabase database) : base(database)
{ {
} }
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
var jobTaskEntityBuilder = new JobTaskEntityBuilder(migrationBuilder, ActiveDatabase); var siteTaskEntityBuilder = new SiteTaskEntityBuilder(migrationBuilder, ActiveDatabase);
jobTaskEntityBuilder.Create(); siteTaskEntityBuilder.Create();
} }
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)

View File

@@ -136,6 +136,6 @@ namespace Oqtane.Repository
public virtual DbSet<MigrationHistory> MigrationHistory { get; set; } public virtual DbSet<MigrationHistory> MigrationHistory { get; set; }
public virtual DbSet<SiteGroup> SiteGroup { get; set; } public virtual DbSet<SiteGroup> SiteGroup { get; set; }
public virtual DbSet<SiteGroupMember> SiteGroupMember { get; set; } public virtual DbSet<SiteGroupMember> SiteGroupMember { get; set; }
public virtual DbSet<JobTask> JobTask { get; set; } public virtual DbSet<SiteTask> SiteTask { get; set; }
} }
} }

View File

@@ -1,56 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Oqtane.Models;
namespace Oqtane.Repository
{
public interface IJobTaskRepository
{
IEnumerable<JobTask> GetJobTasks(int siteId);
JobTask GetJobTask(int jobTaskId);
JobTask AddJobTask(JobTask jobTask);
JobTask UpdateJobTask(JobTask jobTask);
void DeleteJobTask(int jobTaskId);
}
public class JobTaskRepository : IJobTaskRepository
{
private TenantDBContext _db;
public JobTaskRepository(TenantDBContext context)
{
_db = context;
}
public IEnumerable<JobTask> GetJobTasks(int siteId)
{
return _db.JobTask.Where(item => item.SiteId == siteId && !item.IsCompleted).OrderBy(item => item.CreatedOn);
}
public JobTask GetJobTask(int jobTaskId)
{
return _db.JobTask.SingleOrDefault(item => item.JobTaskId == jobTaskId);
}
public JobTask AddJobTask(JobTask jobTask)
{
_db.JobTask.Add(jobTask);
_db.SaveChanges();
return jobTask;
}
public JobTask UpdateJobTask(JobTask jobTask)
{
_db.Entry(jobTask).State = EntityState.Modified;
_db.SaveChanges();
return jobTask;
}
public void DeleteJobTask(int jobTaskId)
{
JobTask jobTask = _db.JobTask.Find(jobTaskId);
_db.JobTask.Remove(jobTask);
_db.SaveChanges();
}
}
}

View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Oqtane.Models;
namespace Oqtane.Repository
{
public interface ISiteTaskRepository
{
IEnumerable<SiteTask> GetSiteTasks(int siteId);
SiteTask GetSiteTask(int siteTaskId);
SiteTask AddSiteTask(SiteTask siteTask);
SiteTask UpdateSiteTask(SiteTask siteTask);
void DeleteSiteTask(int siteTaskId);
int DeleteSiteTasks(int siteId, int age);
}
public class SiteTaskRepository : ISiteTaskRepository
{
private readonly IDbContextFactory<TenantDBContext> _dbContextFactory;
public SiteTaskRepository(IDbContextFactory<TenantDBContext> dbContextFactory)
{
_dbContextFactory = dbContextFactory;
}
public IEnumerable<SiteTask> GetSiteTasks(int siteId)
{
using var db = _dbContextFactory.CreateDbContext();
return db.SiteTask.Where(item => item.SiteId == siteId && !item.IsCompleted).OrderBy(item => item.CreatedOn);
}
public SiteTask GetSiteTask(int siteTaskId)
{
using var db = _dbContextFactory.CreateDbContext();
return db.SiteTask.SingleOrDefault(item => item.SiteTaskId == siteTaskId);
}
public SiteTask AddSiteTask(SiteTask siteTask)
{
using var db = _dbContextFactory.CreateDbContext();
db.SiteTask.Add(siteTask);
db.SaveChanges();
return siteTask;
}
public SiteTask UpdateSiteTask(SiteTask siteTask)
{
using var db = _dbContextFactory.CreateDbContext();
db.Entry(siteTask).State = EntityState.Modified;
db.SaveChanges();
return siteTask;
}
public void DeleteSiteTask(int siteTaskId)
{
using var db = _dbContextFactory.CreateDbContext();
SiteTask siteTask = db.SiteTask.Find(siteTaskId);
db.SiteTask.Remove(siteTask);
db.SaveChanges();
}
public int DeleteSiteTasks(int siteId, int age)
{
using var db = _dbContextFactory.CreateDbContext();
// delete completed tasks in batches of 100 records
var count = 0;
var purgedate = DateTime.UtcNow.AddDays(-age);
var tasks = db.SiteTask.Where(item => item.SiteId == siteId && item.IsCompleted && item.CreatedOn < purgedate)
.OrderBy(item => item.CreatedOn).Take(100).ToList();
while (tasks.Count > 0)
{
count += tasks.Count;
db.SiteTask.RemoveRange(tasks);
db.SaveChanges();
tasks = db.SiteTask.Where(item => item.SiteId == siteId && item.IsCompleted && item.CreatedOn < purgedate)
.OrderBy(item => item.CreatedOn).Take(100).ToList();
}
return count;
}
}
}

View File

@@ -1,16 +1,14 @@
using System;
namespace Oqtane.Models namespace Oqtane.Models
{ {
/// <summary> /// <summary>
/// An instance of a Task which is executed by the TaskJob /// An instance of a SiteTask which is executed by the SiteTaskJob
/// </summary> /// </summary>
public class JobTask : ModelBase public class SiteTask : ModelBase
{ {
/// <summary> /// <summary>
/// Internal ID /// Internal ID
/// </summary> /// </summary>
public int JobTaskId { get; set; } public int SiteTaskId { get; set; }
/// <summary> /// <summary>
/// Site where the Task should execute /// Site where the Task should execute
@@ -43,9 +41,9 @@ namespace Oqtane.Models
public string Status { get; set; } public string Status { get; set; }
// constructors // constructors
public JobTask() { } public SiteTask() { }
public JobTask(int siteId, string name, string type, string parameters) public SiteTask(int siteId, string name, string type, string parameters)
{ {
SiteId = siteId; SiteId = siteId;
Name = name; Name = name;