wabbajack/Wabbajack.Server/DataLayer/Patches.cs

161 lines
6.3 KiB
C#
Raw Normal View History

2020-05-19 03:46:33 +00:00
using System;
2020-05-20 12:18:47 +00:00
using System.Collections.Generic;
using System.Linq;
2020-05-19 03:46:33 +00:00
using System.Threading.Tasks;
using Dapper;
using Wabbajack.Common;
2020-05-20 12:18:47 +00:00
using Wabbajack.Lib;
2020-05-19 03:46:33 +00:00
using Wabbajack.Server.DTOs;
namespace Wabbajack.Server.DataLayer
{
public partial class SqlService
{
/// <summary>
/// Adds a patch record
/// </summary>
/// <param name="patch"></param>
/// <returns></returns>
public async Task AddPatch(Patch patch)
{
await using var conn = await Open();
await conn.ExecuteAsync("INSERT INTO dbo.Patches (SrcId, DestId) VALUES (@SrcId, @DestId)",
new {SrcId = patch.Src.Id, DestId = patch.Dest.Id});
}
/// <summary>
/// Adds a patch record
/// </summary>
/// <param name="patch"></param>
/// <returns></returns>
public async Task FinializePatch(Patch patch)
{
await using var conn = await Open();
2020-05-20 03:25:41 +00:00
await conn.ExecuteAsync("UPDATE dbo.Patches SET PatchSize = @PatchSize, Finished = @Finished, IsFailed = @IsFailed, FailMessage = @FailMessage WHERE SrcId = @SrcId AND DestID = @DestId",
2020-05-19 03:46:33 +00:00
new
{
SrcId = patch.Src.Id,
DestId = patch.Dest.Id,
PatchSize = patch.PatchSize,
2020-05-20 03:25:41 +00:00
Finished = patch.Finished,
IsFailed = patch.IsFailed,
FailMessage = patch.FailMessage
2020-05-19 03:46:33 +00:00
});
}
public async Task<Patch> FindPatch(Guid src, Guid dest)
{
await using var conn = await Open();
2020-05-20 03:25:41 +00:00
var patch = await conn.QueryFirstOrDefaultAsync<(long, DateTime?, bool?, string)>(
@"SELECT p.PatchHash, p.PatchSize, p.Finished, p.IsFailed, p.FailMessage
FROM dbo.Patches p
LEFT JOIN dbo.ArchiveDownloads src ON p.SrcId = src.Id
LEFT JOIN dbo.ArchiveDownloads dest ON p.SrcId = dest.Id
WHERE SrcId = @SrcId
AND DestId = @DestId
AND src.DownloadFinished IS NOT NULL
AND dest.DownloadFinished IS NOT NULL",
2020-05-19 03:46:33 +00:00
new
{
SrcId = src,
DestId = dest
});
if (patch == default)
2020-05-20 03:25:41 +00:00
return default;
2020-05-19 03:46:33 +00:00
return new Patch {
Src = await GetArchiveDownload(src),
Dest = await GetArchiveDownload(dest),
2020-05-20 03:25:41 +00:00
PatchSize = patch.Item1,
Finished = patch.Item2,
IsFailed = patch.Item3,
FailMessage = patch.Item4
2020-05-19 03:46:33 +00:00
};
2020-05-20 03:25:41 +00:00
}
public async Task<Patch> FindOrEnqueuePatch(Guid src, Guid dest)
{
await using var conn = await Open();
var trans = await conn.BeginTransactionAsync();
var patch = await conn.QueryFirstOrDefaultAsync<(Guid, Guid, long, DateTime?, bool?, string)>(
"SELECT SrcId, DestId, PatchSize, Finished, IsFailed, FailMessage FROM dbo.Patches WHERE SrcId = @SrcId AND DestId = @DestId",
2020-05-20 03:25:41 +00:00
new
{
SrcId = src,
DestId = dest
}, trans);
if (patch == default)
{
await conn.ExecuteAsync("INSERT INTO dbo.Patches (SrcId, DestId) VALUES (@SrcId, @DestId)",
new {SrcId = src, DestId = dest}, trans);
await trans.CommitAsync();
return new Patch {Src = await GetArchiveDownload(src), Dest = await GetArchiveDownload(dest),};
}
else
{
return new Patch {
Src = await GetArchiveDownload(src),
Dest = await GetArchiveDownload(dest),
PatchSize = patch.Item3,
Finished = patch.Item4,
IsFailed = patch.Item5,
FailMessage = patch.Item6
2020-05-20 03:25:41 +00:00
};
}
2020-05-19 03:46:33 +00:00
}
2020-05-20 03:25:41 +00:00
public async Task<Patch> GetPendingPatch()
{
await using var conn = await Open();
var patch = await conn.QueryFirstOrDefaultAsync<(Guid, Guid, long, DateTime?, bool?, string)>(
@"SELECT p.SrcId, p.DestId, p.PatchSize, p.Finished, p.IsFailed, p.FailMessage FROM dbo.Patches p
LEFT JOIN dbo.ArchiveDownloads src ON src.Id = p.SrcId
LEFT JOIN dbo.ArchiveDownloads dest ON dest.Id = p.DestId
WHERE p.Finished is NULL AND src.IsFailed = 0 AND dest.IsFailed = 0 ");
2020-05-20 03:25:41 +00:00
if (patch == default)
return default(Patch);
return new Patch {
Src = await GetArchiveDownload(patch.Item1),
Dest = await GetArchiveDownload(patch.Item2),
PatchSize = patch.Item3,
Finished = patch.Item4,
IsFailed = patch.Item5,
FailMessage = patch.Item6
};
}
2020-05-20 12:18:47 +00:00
public async Task<List<Patch>> PatchesForSource(Guid sourceDownload)
{
await using var conn = await Open();
var patches = await conn.QueryAsync<(Guid, Guid, long, DateTime?, bool?, string)>(
"SELECT SrcId, DestId, PatchSize, Finished, IsFailed, FailMessage FROM dbo.Patches WHERE SrcId = @SrcId", new {SrcId = sourceDownload});
List<Patch> results = new List<Patch>();
2020-05-30 21:05:26 +00:00
foreach (var (srcId, destId, patchSize, finished, isFailed, failMessage) in patches)
2020-05-20 12:18:47 +00:00
{
results.Add( new Patch {
Src = await GetArchiveDownload(srcId),
Dest = await GetArchiveDownload(destId),
PatchSize = patchSize,
Finished = finished,
2020-05-30 21:05:26 +00:00
IsFailed = isFailed,
2020-05-20 12:18:47 +00:00
FailMessage = failMessage
});
}
return results;
}
public async Task MarkPatchUsage(Guid srcId, Guid destId)
{
await using var conn = await Open();
await conn.ExecuteAsync(
@"UPDATE dbo.Patches SET Downloads = Downloads + 1, LastUsed = GETUTCDATE() WHERE SrcId = @srcId AND DestID = @destId",
new {SrcId = srcId, DestId = destId});
}
2020-05-19 03:46:33 +00:00
}
}