Skip to content

Commit

Permalink
Merge branch 'feature/555-delete-obsolete-players'
Browse files Browse the repository at this point in the history
  • Loading branch information
sussexrick committed Oct 21, 2023
2 parents b6dee98 + 0e19295 commit 7c8d842
Show file tree
Hide file tree
Showing 39 changed files with 2,881 additions and 494 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public SqlServerStatisticsMaxResultsDataSourceFixture() : base("StoolballStatist
var playerInMatchStatisticsBuilder = new PlayerInMatchStatisticsBuilder(playerIdentityFinder, oversHelper);
var playerOfTheMatchAward = new Award { AwardId = Guid.NewGuid(), AwardName = "Player of the match" };
var seedDataGenerator = new SeedDataGenerator(randomiser, oversHelper, bowlingFiguresCalculator, playerIdentityFinder, matchFinder,
teamFakerFactory: new TeamFakerFactory(), new MatchLocationFakerFactory(), new SchoolFakerFactory(), playerOfTheMatchAward);
teamFakerFactory: new TeamFakerFactory(), new MatchLocationFakerFactory(), new SchoolFakerFactory(), new PlayerIdentityFakerFactory(), playerOfTheMatchAward);
TestData = seedDataGenerator.GenerateTestData();
PlayerWithFifthAndSixthBowlingFiguresTheSame = ForceFifthAndSixthBowlingFiguresToBeTheSame(TestData);
PlayerWithFifthAndSixthInningsTheSame = ForceFifthAndSixthPlayerInningsToBeTheSame(TestData, bowlingFiguresCalculator);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ public SqlServerTestDataFixture() : base("StoolballIntegrationTests")
var teamFakerFactory = new TeamFakerFactory();
var matchLocationFakerFactory = new MatchLocationFakerFactory();
var schoolFakerFactory = new SchoolFakerFactory();
var playerIdentityFakerFactory = new PlayerIdentityFakerFactory();
var playerOfTheMatchAward = new Award { AwardId = Guid.NewGuid(), AwardName = "Player of the match" };
var randomSeedDataGenerator = new SeedDataGenerator(randomiser, oversHelper, bowlingFiguresCalculator, playerIdentityFinder, matchFinder, teamFakerFactory, matchLocationFakerFactory, schoolFakerFactory, playerOfTheMatchAward);
var randomSeedDataGenerator = new SeedDataGenerator(randomiser, oversHelper, bowlingFiguresCalculator, playerIdentityFinder, matchFinder, teamFakerFactory, matchLocationFakerFactory, schoolFakerFactory, playerIdentityFakerFactory, playerOfTheMatchAward);

// Use Bogus to generate Schools data
Randomizer.Seed = new Random(85437684);
Expand Down

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.

Large diffs are not rendered by default.

34 changes: 29 additions & 5 deletions Stoolball.Data.SqlServer/DapperWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,49 @@ public async Task<IEnumerable<T>> QueryAsync<T>(string sql, CommandType commandT
}

/// <inheritdoc/>
public async Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TReturn>(string sql, Func<TFirst, TSecond, TReturn> map, object param, IDbTransaction transaction, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
public async Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TReturn>(string sql, Func<TFirst, TSecond, TReturn> map, object? param, IDbTransaction transaction, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
{
return await transaction.Connection.QueryAsync<TFirst, TSecond, TReturn>(new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None), map, splitOn).ConfigureAwait(false);
return await transaction.Connection.QueryAsync(new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None), map, splitOn).ConfigureAwait(false);
}

/// <inheritdoc/>
public async Task<IEnumerable<T>> QueryAsync<T>(string sql, object param, IDbTransaction transaction)
public async Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TReturn>(string sql, Func<TFirst, TSecond, TThird, TReturn> map, object? param, IDbTransaction transaction, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
{
return await transaction.Connection.QueryAsync(sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType).ConfigureAwait(false);
}

/// <inheritdoc/>
public async Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TFourth, TReturn>(string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, object? param, IDbTransaction transaction, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
{
return await transaction.Connection.QueryAsync(sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType).ConfigureAwait(false);
}

/// <inheritdoc/>
public async Task<T> QuerySingleAsync<T>(string sql, object? param, IDbTransaction transaction, int? commandTimeout = null, CommandType? commandType = null)
{
return await transaction.Connection.QuerySingleAsync<T>(sql, param, transaction, commandTimeout, commandType).ConfigureAwait(false);
}

/// <inheritdoc/>
public async Task<T> QuerySingleOrDefaultAsync<T>(string sql, object? param, IDbTransaction transaction, int? commandTimeout = null, CommandType? commandType = null)
{
return await transaction.Connection.QuerySingleOrDefaultAsync<T>(sql, param, transaction, commandTimeout, commandType).ConfigureAwait(false);
}

/// <inheritdoc/>
public async Task<IEnumerable<T>> QueryAsync<T>(string sql, object? param, IDbTransaction transaction)
{
return await transaction.Connection.QueryAsync<T>(sql, param, transaction).ConfigureAwait(false);
}

/// <inheritdoc/>
public async Task<int> ExecuteAsync(string sql, object param, IDbTransaction transaction)
public async Task<int> ExecuteAsync(string sql, object? param, IDbTransaction transaction)
{
return await transaction.Connection.ExecuteAsync(sql, param, transaction).ConfigureAwait(false);
}

/// <inheritdoc/>
public async Task<T> ExecuteScalarAsync<T>(string sql, object param, IDbTransaction transaction, int? commandTimeout = null, CommandType? commandType = null)
public async Task<T> ExecuteScalarAsync<T>(string sql, object? param, IDbTransaction transaction, int? commandTimeout = null, CommandType? commandType = null)
{
return await transaction.Connection.ExecuteScalarAsync<T>(sql, param, transaction, commandTimeout, commandType).ConfigureAwait(false);
}
Expand Down
69 changes: 65 additions & 4 deletions Stoolball.Data.SqlServer/IDapperWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public interface IDapperWrapper
/// <param name="param"></param>
/// <param name="transaction"></param>
/// <returns></returns>
Task<IEnumerable<T>> QueryAsync<T>(string sql, object param, IDbTransaction transaction);
Task<IEnumerable<T>> QueryAsync<T>(string sql, object? param, IDbTransaction transaction);

/// <summary>
/// Perform a asynchronous multi-mapping query with 2 input types. This returns a single type, combined from the raw types via map.
Expand All @@ -45,7 +45,68 @@ public interface IDapperWrapper
/// <param name="commandTimeout">Number of seconds before command execution timeout.</param>
/// <param name="commandType"> Is it a stored proc or a batch?</param>
/// <returns>An enumerable of TReturn.</returns>
Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TReturn>(string sql, Func<TFirst, TSecond, TReturn> map, object param, IDbTransaction transaction, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null);
Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TReturn>(string sql, Func<TFirst, TSecond, TReturn> map, object? param, IDbTransaction transaction, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null);

/// <summary>
/// Perform a asynchronous multi-mapping query with 3 input types.
/// This returns a single type, combined from the raw types via <paramref name="map"/>.
/// </summary>
/// <typeparam name="TFirst">The first type in the recordset.</typeparam>
/// <typeparam name="TSecond">The second type in the recordset.</typeparam>
/// <typeparam name="TThird">The third type in the recordset.</typeparam>
/// <typeparam name="TReturn">The combined type to return.</typeparam>
/// <param name="sql">The SQL to execute for this query.</param>
/// <param name="map">The function to map row types to the return type.</param>
/// <param name="param">The parameters to use for this query.</param>
/// <param name="transaction">The transaction to use for this query.</param>
/// <param name="buffered">Whether to buffer the results in memory.</param>
/// <param name="splitOn">The field we should split and read the second object from (default: "Id").</param>
/// <param name="commandTimeout">Number of seconds before command execution timeout.</param>
/// <param name="commandType">Is it a stored proc or a batch?</param>
/// <returns>An enumerable of <typeparamref name="TReturn"/>.</returns>
Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TReturn>(string sql, Func<TFirst, TSecond, TThird, TReturn> map, object? param, IDbTransaction transaction, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null);

/// <summary>
/// Perform a asynchronous multi-mapping query with 4 input types.
/// This returns a single type, combined from the raw types via <paramref name="map"/>.
/// </summary>
/// <typeparam name="TFirst">The first type in the recordset.</typeparam>
/// <typeparam name="TSecond">The second type in the recordset.</typeparam>
/// <typeparam name="TThird">The third type in the recordset.</typeparam>
/// <typeparam name="TFourth">The fourth type in the recordset.</typeparam>
/// <typeparam name="TReturn">The combined type to return.</typeparam>
/// <param name="sql">The SQL to execute for this query.</param>
/// <param name="map">The function to map row types to the return type.</param>
/// <param name="param">The parameters to use for this query.</param>
/// <param name="transaction">The transaction to use for this query.</param>
/// <param name="buffered">Whether to buffer the results in memory.</param>
/// <param name="splitOn">The field we should split and read the second object from (default: "Id").</param>
/// <param name="commandTimeout">Number of seconds before command execution timeout.</param>
/// <param name="commandType">Is it a stored proc or a batch?</param>
/// <returns>An enumerable of <typeparamref name="TReturn"/>.</returns>
Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TFourth, TReturn>(string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, object? param, IDbTransaction transaction, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null);

/// <summary>
/// Execute a single-row query asynchronously using Task.
/// </summary>
/// <typeparam name="T">The type of result to return.</typeparam>
/// <param name="sql">The SQL to execute for the query.</param>
/// <param name="param">The parameters to pass, if any.</param>
/// <param name="transaction">The transaction to use, if any.</param>
/// <param name="commandTimeout">The command timeout (in seconds).</param>
/// <param name="commandType">The type of command to execute.</param>
Task<T> QuerySingleAsync<T>(string sql, object? param, IDbTransaction transaction, int? commandTimeout = null, CommandType? commandType = null);

/// <summary>
/// Execute a single-row query asynchronously using Task.
/// </summary>
/// <typeparam name="T">The type to return.</typeparam>
/// <param name="sql">The SQL to execute for the query.</param>
/// <param name="param">The parameters to pass, if any.</param>
/// <param name="transaction">The transaction to use, if any.</param>
/// <param name="commandTimeout">The command timeout (in seconds).</param>
/// <param name="commandType">The type of command to execute.</param>
Task<T> QuerySingleOrDefaultAsync<T>(string sql, object? param, IDbTransaction transaction, int? commandTimeout = null, CommandType? commandType = null);

/// <summary>
/// Execute a command asynchronously using Task
Expand All @@ -55,7 +116,7 @@ public interface IDapperWrapper
/// <param name="param"></param>
/// <param name="transaction"></param>
/// <returns>The number of rows affected</returns>
Task<int> ExecuteAsync(string sql, object param, IDbTransaction transaction);
Task<int> ExecuteAsync(string sql, object? param, IDbTransaction transaction);

/// <summary>
/// Execute parameterized SQL that selects a single value.
Expand All @@ -67,6 +128,6 @@ public interface IDapperWrapper
/// <param name="commandTimeout">Number of seconds before command execution timeout.</param>
/// <param name="commandType">Is it a stored proc or a batch?</param>
/// <returns>The first cell returned, as <typeparamref name="T"/>.</returns>
Task<T> ExecuteScalarAsync<T>(string sql, object param, IDbTransaction transaction, int? commandTimeout = null, CommandType? commandType = null);
Task<T> ExecuteScalarAsync<T>(string sql, object? param, IDbTransaction transaction, int? commandTimeout = null, CommandType? commandType = null);
}
}
10 changes: 10 additions & 0 deletions Stoolball.Data.SqlServer/SqlConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,14 @@ public static class Tables
public const string UmbracoNode = "umbracoNode";
public const string UmbracoMember = "cmsMember";
}

public static class Views
{
internal const string _viewPrefix = "vw_Stoolball_";

/// <summary>
/// Player identities with player information, excluding those which have been soft deleted.
/// </summary>
public const string PlayerIdentity = _viewPrefix + "PlayerIdentity";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public async Task<IEnumerable<StatisticsResult<BestStatistic>>> ReadMostRunsScor
) AS BestTotal
ORDER BY Total DESC, TotalInnings ASC, TotalMatches ASC";

var extraSelectFields = $", (SELECT COUNT(PlayerInMatchStatisticsId) FROM { Tables.PlayerInMatchStatistics } WHERE PlayerId = s.PlayerId AND PlayerWasDismissed = 1 AND RunsScored IS NOT NULL <<WHERE>>) AS TotalDismissals";
var extraSelectFields = $", (SELECT COUNT(PlayerInMatchStatisticsId) FROM {Tables.PlayerInMatchStatistics} WHERE PlayerId = s.PlayerId AND PlayerWasDismissed = 1 AND RunsScored IS NOT NULL <<WHERE>>) AS TotalDismissals";

return await ReadBestPlayerSum("RunsScored", true, false, extraSelectFields, outerQuery, $"AND RunsScored IS NOT NULL", filter).ConfigureAwait(false);
}
Expand Down Expand Up @@ -185,12 +185,12 @@ private async Task<IEnumerable<StatisticsResult<BestStatistic>>> ReadBestPlayerS
parameters.Add("@PageSize", clonedFilter.Paging.PageSize);
}

var totalInningsQuery = !string.IsNullOrEmpty(totalInningsFilter) ? $"SELECT COUNT(PlayerInMatchStatisticsId) FROM { Tables.PlayerInMatchStatistics} WHERE PlayerId = s.PlayerId {totalInningsFilter} {where}" : "NULL";
var totalInningsQuery = !string.IsNullOrEmpty(totalInningsFilter) ? $"SELECT COUNT(PlayerInMatchStatisticsId) FROM {Tables.PlayerInMatchStatistics} WHERE PlayerId = s.PlayerId {totalInningsFilter} {where}" : "NULL";

var sql = $@"SELECT PlayerId,
(SELECT COUNT(DISTINCT MatchId) FROM { Tables.PlayerInMatchStatistics} WHERE PlayerId = s.PlayerId {where}) AS TotalMatches,
(SELECT COUNT(DISTINCT MatchId) FROM {Tables.PlayerInMatchStatistics} WHERE PlayerId = s.PlayerId {where}) AS TotalMatches,
({totalInningsQuery}) AS TotalInnings,
(SELECT SUM({ fieldName}) FROM { Tables.PlayerInMatchStatistics} WHERE PlayerId = s.PlayerId {where}) AS Total
(SELECT SUM({fieldName}) FROM {Tables.PlayerInMatchStatistics} WHERE PlayerId = s.PlayerId {where}) AS Total
<<SELECT>>
FROM {Tables.PlayerInMatchStatistics} AS s
WHERE {fieldName} IS NOT NULL {minimumValue} {where}
Expand Down Expand Up @@ -228,8 +228,8 @@ private async Task<IEnumerable<StatisticsResult<BestStatistic>>> ReadBestPlayerC
var (whereWithoutMinimumPerformance, _) = _statisticsQueryBuilder.BuildWhereClause(filterWithoutMinimumPerformance);

var sql = @$"SELECT PlayerId,
(SELECT COUNT(DISTINCT MatchId) FROM { Tables.PlayerInMatchStatistics } WHERE PlayerId = s.PlayerId {whereWithoutMinimumPerformance}) AS TotalMatches,
(SELECT COUNT(PlayerInMatchStatisticsId) FROM { Tables.PlayerInMatchStatistics} WHERE PlayerId = s.PlayerId {totalInningsFilter} {whereWithoutMinimumPerformance}) AS TotalInnings,
(SELECT COUNT(DISTINCT MatchId) FROM {Tables.PlayerInMatchStatistics} WHERE PlayerId = s.PlayerId {whereWithoutMinimumPerformance}) AS TotalMatches,
(SELECT COUNT(PlayerInMatchStatisticsId) FROM {Tables.PlayerInMatchStatistics} WHERE PlayerId = s.PlayerId {totalInningsFilter} {whereWithoutMinimumPerformance}) AS TotalInnings,
COUNT({fieldName}) AS Total
FROM {Tables.PlayerInMatchStatistics} s
WHERE {fieldName} IS NOT NULL {where}
Expand Down Expand Up @@ -271,10 +271,5 @@ private async Task<IEnumerable<StatisticsResult<BestStatistic>>> ReadResults(str
return results;
}
}

public Task<IEnumerable<StatisticsResult<BestStatistic>>> ReadMostBowlingFigures(StatisticsFilter filter)
{
throw new NotImplementedException();
}
}
}
Loading

0 comments on commit 7c8d842

Please sign in to comment.