Skip to content

Commit d010d6f

Browse files
committed
Merge branch 'DLS-Release-v1.2.2' into UAT
2 parents e5c7fe5 + a17a7cd commit d010d6f

File tree

8 files changed

+57
-40
lines changed

8 files changed

+57
-40
lines changed

DigitalLearningSolutions.Data/DataServices/PlatformReportsDataService.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
namespace DigitalLearningSolutions.Data.DataServices
22
{
33
using Dapper;
4+
using DigitalLearningSolutions.Data.Factories;
45
using DigitalLearningSolutions.Data.Models.PlatformReports;
5-
using DigitalLearningSolutions.Data.Models.SelfAssessments;
66
using DigitalLearningSolutions.Data.Models.TrackingSystem;
7-
using Microsoft.Extensions.Logging;
87
using System;
98
using System.Collections.Generic;
109
using System.Data;
@@ -37,9 +36,9 @@ IEnumerable<ActivityLog> GetFilteredCourseActivity(
3736
);
3837
DateTime? GetStartOfCourseActivity();
3938
}
40-
public class PlatformReportsDataService : IPlatformReportsDataService
39+
public class PlatformReportsDataService(IReadOnlyDbConnectionFactory factory) : IPlatformReportsDataService
4140
{
42-
private readonly IDbConnection connection;
41+
private readonly IDbConnection connection = factory.CreateConnection();
4342
private readonly string selectSelfAssessmentActivity = @"SELECT Cast(al.ActivityDate As Date) As ActivityDate, SUM(CAST(al.Enrolled AS Int)) AS Enrolled, SUM(CAST((al.Submitted | al.SignedOff) AS Int)) AS Completed
4443
FROM ReportSelfAssessmentActivityLog AS al WITH (NOLOCK) INNER JOIN
4544
Centres AS ce WITH (NOLOCK) ON al.CentreID = ce.CentreID INNER JOIN
@@ -60,10 +59,6 @@ private string GetSelfAssessmentWhereClause(bool supervised)
6059
return supervised ? " (sa.SupervisorResultsReview = 1 OR SupervisorSelfAssessmentReview = 1)" : " (sa.SupervisorResultsReview = 0 AND SupervisorSelfAssessmentReview = 0)";
6160
}
6261

63-
public PlatformReportsDataService(IDbConnection connection)
64-
{
65-
this.connection = connection;
66-
}
6762
public PlatformUsageSummary GetPlatformUsageSummary()
6863
{
6964
return connection.QueryFirstOrDefault<PlatformUsageSummary>(

DigitalLearningSolutions.Data/DataServices/SelfAssessmentDataService/DCSAReportDataService.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace DigitalLearningSolutions.Data.DataServices.SelfAssessmentDataService
22
{
33
using Dapper;
4+
using DigitalLearningSolutions.Data.Factories;
45
using DigitalLearningSolutions.Data.Models.SelfAssessments.Export;
56
using Microsoft.Extensions.Logging;
67
using System.Collections.Generic;
@@ -11,16 +12,10 @@ public interface IDCSAReportDataService
1112
IEnumerable<DCSADelegateCompletionStatus> GetDelegateCompletionStatusForCentre(int centreId);
1213
IEnumerable<DCSAOutcomeSummary> GetOutcomeSummaryForCentre(int centreId);
1314
}
14-
public partial class DCSAReportDataService : IDCSAReportDataService
15+
public partial class DCSAReportDataService(IReadOnlyDbConnectionFactory factory, ILogger<SelfAssessmentDataService> logger) : IDCSAReportDataService
1516
{
16-
private readonly IDbConnection connection;
17-
private readonly ILogger<SelfAssessmentDataService> logger;
18-
19-
public DCSAReportDataService(IDbConnection connection, ILogger<SelfAssessmentDataService> logger)
20-
{
21-
this.connection = connection;
22-
this.logger = logger;
23-
}
17+
private readonly IDbConnection connection = factory.CreateConnection();
18+
private readonly ILogger<SelfAssessmentDataService> logger = logger;
2419

2520
public IEnumerable<DCSADelegateCompletionStatus> GetDelegateCompletionStatusForCentre(int centreId)
2621
{

DigitalLearningSolutions.Data/DataServices/SelfAssessmentDataService/SelfAsssessmentReportDataService.cs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,17 @@
66
using Microsoft.Extensions.Logging;
77
using System.Collections.Generic;
88
using System.Data;
9-
using ClosedXML.Excel;
9+
using DigitalLearningSolutions.Data.Factories;
1010

1111
public interface ISelfAssessmentReportDataService
1212
{
1313
IEnumerable<SelfAssessmentSelect> GetSelfAssessmentsForReportList(int centreId, int? categoryId);
1414
IEnumerable<SelfAssessmentReportData> GetSelfAssessmentReportDataForCentre(int centreId, int selfAssessmentId);
1515
}
16-
public partial class SelfAssessmentReportDataService : ISelfAssessmentReportDataService
16+
public partial class SelfAssessmentReportDataService(IReadOnlyDbConnectionFactory factory, ILogger<SelfAssessmentReportDataService> logger) : ISelfAssessmentReportDataService
1717
{
18-
private readonly IDbConnection connection;
19-
private readonly ILogger<SelfAssessmentReportDataService> logger;
20-
21-
public SelfAssessmentReportDataService(IDbConnection connection, ILogger<SelfAssessmentReportDataService> logger)
22-
{
23-
this.connection = connection;
24-
this.logger = logger;
25-
}
18+
private readonly IDbConnection connection = factory.CreateConnection();
19+
private readonly ILogger<SelfAssessmentReportDataService> logger = logger;
2620

2721
public IEnumerable<SelfAssessmentSelect> GetSelfAssessmentsForReportList(int centreId, int? categoryId)
2822
{

DigitalLearningSolutions.Data/DigitalLearningSolutions.Data.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<PackageReference Include="Freshdesk.Api" Version="0.17.2" />
1818
<PackageReference Include="FuzzySharp" Version="2.0.2" />
1919
<PackageReference Include="MailKit" Version="4.3.0" />
20+
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.1" />
2021
<PackageReference Include="Microsoft.FeatureManagement.AspNetCore" Version="2.0.0" />
2122
<PackageReference Include="Serilog.AspNetCore" Version="7.0.0" />
2223
<PackageReference Include="System.Drawing.Common" Version="9.0.1" />
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace DigitalLearningSolutions.Data.Factories
2+
{
3+
using Microsoft.Data.SqlClient;
4+
using Microsoft.Extensions.Configuration;
5+
using System;
6+
using System.Data;
7+
public interface IReadOnlyDbConnectionFactory
8+
{
9+
IDbConnection CreateConnection();
10+
}
11+
public class ReadOnlyDbConnectionFactory : IReadOnlyDbConnectionFactory
12+
{
13+
private const string ReadOnlyConnectionName = "ReadOnlyConnection";
14+
private readonly string connectionString;
15+
16+
public ReadOnlyDbConnectionFactory(IConfiguration config)
17+
{
18+
// Ensure the connection string is not null to avoid CS8601
19+
connectionString = config.GetConnectionString(ReadOnlyConnectionName)
20+
?? throw new InvalidOperationException($"Connection string '{ReadOnlyConnectionName}' is not configured.");
21+
}
22+
23+
public IDbConnection CreateConnection()
24+
{
25+
// Ensure the connection is not enlisted in the trasaction scope to avoid distributed transaction errors:
26+
return new SqlConnection(connectionString + ";Enlist=false");
27+
}
28+
}
29+
}

DigitalLearningSolutions.Web/Helpers/ConfigHelper.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
public static class ConfigHelper
99
{
1010
public const string DefaultConnectionStringName = "DefaultConnection";
11+
public const string ReadOnlyConnectionStringName = "ReadOnlyConnection";
1112
public const string UnitTestConnectionStringName = "UnitTestConnection";
1213

1314
public static IConfigurationRoot GetAppConfig()

DigitalLearningSolutions.Web/Startup.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
namespace DigitalLearningSolutions.Web
22
{
3-
using System.Collections.Generic;
4-
using System.Data;
5-
using System.IO;
6-
using System.Linq;
7-
using System.Security.Claims;
8-
using System.Threading.Tasks;
9-
using System.Transactions;
10-
using System.Web;
113
using AspNetCoreRateLimit;
124
using DigitalLearningSolutions.Data.ApiClients;
135
using DigitalLearningSolutions.Data.DataServices;
@@ -39,19 +31,27 @@ namespace DigitalLearningSolutions.Web
3931
using Microsoft.AspNetCore.Builder;
4032
using Microsoft.AspNetCore.DataProtection;
4133
using Microsoft.AspNetCore.HttpOverrides;
34+
using Microsoft.AspNetCore.Identity;
4235
using Microsoft.AspNetCore.Mvc;
4336
using Microsoft.Data.SqlClient;
4437
using Microsoft.Extensions.Configuration;
4538
using Microsoft.Extensions.DependencyInjection;
4639
using Microsoft.Extensions.Hosting;
4740
using Microsoft.FeatureManagement;
4841
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
49-
using Microsoft.AspNetCore.Identity;
42+
using Serilog;
43+
using System;
44+
using System.Collections.Generic;
45+
using System.Data;
46+
using System.IO;
47+
using System.Linq;
48+
using System.Security.Claims;
49+
using System.Threading.Tasks;
50+
using System.Transactions;
51+
using System.Web;
5052
using static DigitalLearningSolutions.Data.DataServices.ICentreApplicationsDataService;
5153
using static DigitalLearningSolutions.Web.Services.ICentreApplicationsService;
5254
using static DigitalLearningSolutions.Web.Services.ICentreSelfAssessmentsService;
53-
using System;
54-
using Serilog;
5555

5656
public class Startup
5757
{
@@ -65,7 +65,6 @@ public Startup(IConfiguration config, IHostEnvironment env)
6565
this.config = config;
6666
this.env = env;
6767
}
68-
6968
public void ConfigureServices(IServiceCollection services)
7069
{
7170
ConfigureIpRateLimiting(services);
@@ -194,6 +193,8 @@ public void ConfigureServices(IServiceCollection services)
194193

195194
// Register database connection for Dapper.
196195
services.AddScoped<IDbConnection>(_ => new SqlConnection(defaultConnectionString));
196+
// Register factory for read-only replica connections
197+
services.AddScoped<IReadOnlyDbConnectionFactory, ReadOnlyDbConnectionFactory>();
197198
Dapper.SqlMapper.Settings.CommandTimeout = 60;
198199

199200
MultiPageFormService.InitConnection(new SqlConnection(defaultConnectionString));
@@ -510,6 +511,7 @@ private static void RegisterDataServices(IServiceCollection services)
510511
services.AddScoped<IRoleProfileDataService, RoleProfileDataService>();
511512
services.AddScoped<ISectionContentDataService, SectionContentDataService>();
512513
services.AddScoped<ISelfAssessmentDataService, SelfAssessmentDataService>();
514+
services.AddScoped<ISelfAssessmentReportDataService, SelfAssessmentReportDataService>();
513515
services.AddScoped<ISessionDataService, SessionDataService>();
514516
services.AddScoped<ISupervisorDataService, SupervisorDataService>();
515517
services.AddScoped<ISupervisorDelegateDataService, SupervisorDelegateDataService>();
@@ -525,7 +527,6 @@ private static void RegisterDataServices(IServiceCollection services)
525527
services.AddScoped<ICacheService, CacheService>();
526528
services.AddScoped<RedisCacheOptions, RedisCacheOptions>();
527529
services.AddScoped<IMultiPageFormService, MultiPageFormService>();
528-
services.AddScoped<ISelfAssessmentReportDataService, SelfAssessmentReportDataService>();
529530
services.AddScoped<IUserFeedbackDataService, UserFeedbackDataService>();
530531
services.AddScoped<IPlatformReportsDataService, PlatformReportsDataService>();
531532
services.AddScoped<IContractTypesDataService, ContractTypesDataService>();

DigitalLearningSolutions.Web/appsettings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"AllowedHosts": "*",
33
"ConnectionStrings": {
44
"DefaultConnection": "Data Source=localhost;Initial Catalog=mbdbx101_uar;Integrated Security=True;encrypt=false;TrustServerCertificate=true;",
5+
"ReadOnlyConnection": "Data Source=localhost;Initial Catalog=mbdbx101_uar;Integrated Security=True;encrypt=false;TrustServerCertificate=true;",
56
"UnitTestConnection": "Data Source=localhost;Initial Catalog=mbdbx101_uar_test;Integrated Security=True;encrypt=false;TrustServerCertificate=true;"
67
},
78
"CurrentSystemBaseUrl": "https://www.dls.nhs.uk",

0 commit comments

Comments
 (0)