Skip to content

Commit 219bebe

Browse files
committed
Added the ability to find specific incidents using tags
1 parent bb8d5ae commit 219bebe

File tree

20 files changed

+269
-33
lines changed

20 files changed

+269
-33
lines changed

src/Server/Coderr.Server.Api/Core/Incidents/Queries/FindIncidents.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,7 @@ public FindIncidents()
9595
/// Version (in the form of a version string i.e. "1.2.1")
9696
/// </summary>
9797
public string Version { get; set; }
98+
99+
public string[] Tags { get; set; }
98100
}
99101
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using DotNetCqs;
3+
4+
namespace codeRR.Server.Api.Modules.Tagging.Queries
5+
{
6+
/// <summary>
7+
/// Get all tags that the system have identified for an incident.
8+
/// </summary>
9+
[Message]
10+
public class GetTagsForApplication : Query<TagDTO[]>
11+
{
12+
/// <summary>
13+
/// Creates a new instance of <see cref="GetTagsForIncident" />.
14+
/// </summary>
15+
/// <param name="applicationId">Incident to get tags for</param>
16+
/// <exception cref="ArgumentOutOfRangeException">incidentId</exception>
17+
public GetTagsForApplication(int applicationId)
18+
{
19+
if (applicationId <= 0) throw new ArgumentOutOfRangeException("applicationId");
20+
ApplicationId = applicationId;
21+
}
22+
23+
/// <summary>
24+
/// Incident to get tags for
25+
/// </summary>
26+
public int ApplicationId { get; private set; }
27+
}
28+
}

src/Server/Coderr.Server.App/GlobalSuppressions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[assembly:
77
SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member",
88
Target =
9-
"codeRR.App.Modules.Tagging.Handlers.GetTagsForIncidentHandler.#.ctor(codeRR.App.Modules.Tagging.ITagsRepository)"
9+
"codeRR.App.Modules.Tagging.Handlers.GetTagsForApplicationHandler.#.ctor(codeRR.App.Modules.Tagging.ITagsRepository)"
1010
)]
1111
[assembly:
1212
SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member",
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.Linq;
2+
using System.Threading.Tasks;
3+
using codeRR.Server.Api.Modules.Tagging;
4+
using codeRR.Server.Api.Modules.Tagging.Queries;
5+
using codeRR.Server.App.Modules.Tagging.Domain;
6+
using DotNetCqs;
7+
using Griffin.Container;
8+
9+
namespace codeRR.Server.App.Modules.Tagging.Handlers
10+
{
11+
[Component]
12+
internal class GetTagsForApplicationHandler : IQueryHandler<GetTagsForApplication, TagDTO[]>
13+
{
14+
private readonly ITagsRepository _repository;
15+
16+
public GetTagsForApplicationHandler(ITagsRepository repository)
17+
{
18+
_repository = repository;
19+
}
20+
21+
public async Task<TagDTO[]> HandleAsync(IMessageContext context, GetTagsForApplication query)
22+
{
23+
return (await _repository.GetApplicationTagsAsync(query.ApplicationId)).Select(ConvertTag).ToArray();
24+
}
25+
26+
private TagDTO ConvertTag(Tag arg)
27+
{
28+
return new TagDTO {Name = arg.Name, OrderNumber = arg.OrderNumber};
29+
}
30+
}
31+
}

src/Server/Coderr.Server.App/Modules/Tagging/Handlers/GetTagsForIncidentHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public GetTagsForIncidentHandler(ITagsRepository repository)
2020

2121
public async Task<TagDTO[]> HandleAsync(IMessageContext context, GetTagsForIncident query)
2222
{
23-
return (await _repository.GetTagsAsync(query.IncidentId)).Select(ConvertTag).ToArray();
23+
return (await _repository.GetIncidentTagsAsync(query.IncidentId)).Select(ConvertTag).ToArray();
2424
}
2525

2626
private TagDTO ConvertTag(Tag arg)

src/Server/Coderr.Server.App/Modules/Tagging/Handlers/IdentifyTagsFromIncident.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public IdentifyTagsFromIncident(ITagsRepository repository, ITagIdentifierProvid
4040
public async Task HandleAsync(IMessageContext context, ReportAddedToIncident e)
4141
{
4242
_logger.Debug("Checking tags..");
43-
var tags = await _repository.GetTagsAsync(e.Incident.Id);
43+
var tags = await _repository.GetIncidentTagsAsync(e.Incident.Id);
4444
var ctx = new TagIdentifierContext(e.Report, tags);
4545
var identifiers = _tagIdentifierProvider.GetIdentifiers(ctx);
4646
foreach (var identifier in identifiers)

src/Server/Coderr.Server.App/Modules/Tagging/Handlers/IncidentReopenedHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public IncidentReopenedHandler(ITagsRepository repository)
3030
/// <inheritdoc />
3131
public async Task HandleAsync(IMessageContext context, IncidentReOpened e)
3232
{
33-
var tags = await _repository.GetTagsAsync(e.IncidentId);
33+
var tags = await _repository.GetIncidentTagsAsync(e.IncidentId);
3434
if (tags.Any(x => x.Name == "incident-reopened"))
3535
return;
3636

src/Server/Coderr.Server.App/Modules/Tagging/ITagsRepository.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,19 @@ public interface ITagsRepository
1919
Task AddAsync(int incidentId, Tag[] tags);
2020

2121
/// <summary>
22-
/// Get a list of tag
22+
/// Get a list of tags for a specific incident
2323
/// </summary>
2424
/// <param name="incidentId">incident to get tags for</param>
2525
/// <returns>List of tags (or an empty list)</returns>
2626
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
27-
Task<IReadOnlyList<Tag>> GetTagsAsync(int incidentId);
27+
Task<IReadOnlyList<Tag>> GetIncidentTagsAsync(int incidentId);
28+
29+
/// <summary>
30+
/// Get a list of tags for an application
31+
/// </summary>
32+
/// <param name="applicationId">application to get tags for</param>
33+
/// <returns>List of tags (or an empty list)</returns>
34+
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
35+
Task<IReadOnlyList<Tag>> GetApplicationTagsAsync(int applicationId);
2836
}
2937
}

src/Server/Coderr.Server.SqlServer/Core/Incidents/Queries/FindIncidentsHandler.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,26 @@ FROM Incidents
4343
cmd.AddParameter("versionId", versionId);
4444
startWord = " AND ";
4545
}
46+
if (query.Tags != null && query.Tags.Length > 0 && query.ApplicationId > 0)
47+
{
48+
var ourSql= @" join IncidentTags on (Incidents.Id=IncidentTags.IncidentId AND IncidentTags.Id IN (
49+
SELECT MAX(IncidentTags.Id)
50+
FROM IncidentTags
51+
WHERE TagName IN ({0})
52+
AND IncidentTags.IncidentId=Incidents.Id
53+
GROUP BY IncidentId
54+
HAVING Count(IncidentTags.Id) = {1}
55+
))
56+
";
57+
var ps = "";
58+
for (int i = 0; i < query.Tags.Length; i++)
59+
{
60+
ps += $"@tag{i}, ";
61+
cmd.AddParameter($"@tag{i}", query.Tags[i]);
62+
}
63+
64+
sqlQuery += string.Format(ourSql, ps.Remove(ps.Length - 2, 2), query.Tags.Length);
65+
}
4666

4767
if (query.ApplicationId > 0)
4868
{

src/Server/Coderr.Server.SqlServer/Modules/Tagging/TagsRepository.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public async Task AddAsync(int incidentId, Tag[] tags)
3333
}
3434
}
3535

36-
public async Task<IReadOnlyList<Tag>> GetTagsAsync(int incidentId)
36+
public async Task<IReadOnlyList<Tag>> GetIncidentTagsAsync(int incidentId)
3737
{
3838
using (var cmd = _adoNetUnitOfWork.CreateDbCommand())
3939
{
@@ -51,5 +51,28 @@ public async Task<IReadOnlyList<Tag>> GetTagsAsync(int incidentId)
5151
}
5252
}
5353
}
54+
55+
public async Task<IReadOnlyList<Tag>> GetApplicationTagsAsync(int applicationId)
56+
{
57+
using (var cmd = _adoNetUnitOfWork.CreateDbCommand())
58+
{
59+
cmd.CommandText = @"select TagName, min(OrderNumber)
60+
FROM IncidentTags
61+
INNER JOIN Incidents ON (IncidentTags.IncidentId=Incidents.Id)
62+
WHERE Incidents.ApplicationId = @id
63+
GROUP BY TagName";
64+
cmd.AddParameter("id", applicationId);
65+
using (var reader = await cmd.ExecuteReaderAsync())
66+
{
67+
var tags = new List<Tag>();
68+
while (await reader.ReadAsync())
69+
{
70+
var tag = new Tag((string) reader[0], (int) reader[1]);
71+
tags.Add(tag);
72+
}
73+
return tags;
74+
}
75+
}
76+
}
5477
}
5578
}

0 commit comments

Comments
 (0)