Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
572 changes: 280 additions & 292 deletions .editorconfig

Large diffs are not rendered by default.

15 changes: 12 additions & 3 deletions .github/workflows/main_astar-dev.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build .NET Core application
name: Build and analyse the DatabaseTesting Solution
on:
pull_request:
types: [ opened, synchronize, reopened ]
Expand Down Expand Up @@ -50,14 +50,23 @@ jobs:
New-Item -Path .\.sonar\scanner -ItemType Directory
dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner

- name: 🔍 Restore, 🛠 Build and 🧪 Test with ☁️ SonarCloud / Qube
- name: 🔍 Restore,
shell: powershell
run: |
dotnet restore

- name: 🛠 Build
shell: powershell
run: |
dotnet build --no-restore

- name: 🧪 Test and analyse with ☁️ SonarCloud / Qube
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
shell: powershell
run: |
dotnet tool install --global dotnet-coverage
.\.sonar\scanner\dotnet-sonarscanner begin /k:"astar-development_astar-dev-database-testing" /o:"astar-development" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.scanner.scanAll=false /d:sonar.scanner.skipJreProvisioning=true
dotnet build
dotnet-coverage collect 'dotnet test --filter "FullyQualifiedName!~Tests.EndToEnd"' -f xml -o 'coverage.xml'
.\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,29 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AStar.Dev.Functional.Extensions" Version="0.2.0" />
<PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" Version="22.0.15" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.7" />
<PackageReference Include="AStar.Dev.Functional.Extensions" Version="0.2.0"/>
<PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" Version="22.0.15"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.7"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.7"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<None Include="LICENSE" Pack="true" PackagePath="" />
<None Include="Readme.md" Pack="true" PackagePath="" />
<None Include="LICENSE" Pack="true" PackagePath=""/>
<None Include="Readme.md" Pack="true" PackagePath=""/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\support\AStar.Dev.Technical.Debt.Reporting\AStar.Dev.Technical.Debt.Reporting.csproj"/>
<ProjectReference Include="..\..\support\AStar.Dev.Utilities\AStar.Dev.Utilities.csproj"/>
<ProjectReference Include="..\AStar.Dev.Infrastructure\AStar.Dev.Infrastructure.csproj" />
<ProjectReference Include="..\AStar.Dev.Infrastructure\AStar.Dev.Infrastructure.csproj"/>
</ItemGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ namespace AStar.Dev.Infrastructure.FilesDb.Data.Configurations;

internal sealed class DirectoryNameConfiguration : IComplexPropertyConfiguration<DirectoryName>
{
public void Configure(ComplexPropertyBuilder<DirectoryName> builder)
{
public void Configure(ComplexPropertyBuilder<DirectoryName> builder) =>
builder.Property(directoryName => directoryName.Value)
.HasColumnName("DirectoryName")
.HasColumnType("nvarchar(256)");
}
.HasColumnName("DirectoryName")
.HasColumnType("nvarchar(256)");
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using AStar.Dev.Infrastructure.Data.Configurations;
using AStar.Dev.Infrastructure.Data.Configurations;
using AStar.Dev.Infrastructure.FilesDb.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
Expand All @@ -19,10 +19,7 @@ public void Configure(EntityTypeBuilder<FileDetail> builder)
builder.Property(file => file.Id)
.HasConversion(fileId => fileId.Value, fileId => new (fileId));

builder.Property(file => file.FileName)
.HasColumnType("nvarchar(256)")
.HasConversion(fileName => fileName.Value, fileName => new (fileName));

builder.Ignore(fileDetail => fileDetail.FileName);
builder.Ignore(fileDetail => fileDetail.DirectoryName);
builder.Ignore(fileDetail => fileDetail.FullNameWithPath);

Expand All @@ -31,16 +28,23 @@ public void Configure(EntityTypeBuilder<FileDetail> builder)
.HasConversion(fileHandle => fileHandle.Value, fileHandle => new (fileHandle));

builder.ComplexProperty(fileDetail => fileDetail.ImageDetail)
.Configure(new ImageDetailConfiguration());
.Configure(new ImageDetailConfiguration());

builder.ComplexProperty(fileDetail => fileDetail.DirectoryName)
.Configure(new DirectoryNameConfiguration());
.Configure(new DirectoryNameConfiguration());

builder.ComplexProperty(fileDetail => fileDetail.FileName)
.Configure(new FileNameConfiguration());

builder.ComplexProperty(fileDetail => fileDetail.DeletionStatus)
.Configure(new DeletionStatusConfiguration());

// Will want the handle to be unique, but not yet
builder.HasIndex(fileDetail => fileDetail.FileHandle);
builder.HasIndex(fileDetail => fileDetail.FileName);
builder.HasIndex(fileDetail => fileDetail.FileHandle).IsUnique();
builder.HasIndex(fileDetail => fileDetail.FileSize);

// Composite index to optimize duplicate images search (partial optimization)
// Note: ImageHeight and ImageWidth can't be indexed directly as they're complex properties
builder.HasIndex(fileDetail => new { fileDetail.IsImage, fileDetail.FileSize })
.HasDatabaseName("IX_FileDetail_DuplicateImages");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using AStar.Dev.Infrastructure.Data.Configurations;
using AStar.Dev.Infrastructure.FilesDb.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace AStar.Dev.Infrastructure.FilesDb.Data.Configurations;

internal sealed class FileNameConfiguration : IComplexPropertyConfiguration<FileName>
{
public void Configure(ComplexPropertyBuilder<FileName> builder) =>
builder.Property(fileName => fileName.Value)
.HasColumnName("FileName")
.HasColumnType("nvarchar(256)");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using AStar.Dev.Infrastructure.FilesDb.Models;

namespace AStar.Dev.Infrastructure.FilesDb.Data;

/// <summary>
/// </summary>
public static class FileDetailDeletionStatusExtensions
{
/// <summary>
/// </summary>
/// <param name="files"></param>
/// <param name="includeDeleted"></param>
/// <returns></returns>
public static IQueryable<FileDetail> IncludeDeletedOrDeletePending(this IQueryable<FileDetail> files, bool includeDeleted)
=> includeDeleted
? files
: files.Where(f => f.DeletionStatus.HardDeletePending == null
&& f.DeletionStatus.SoftDeletePending == null
&& f.DeletionStatus.SoftDeleted == null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@
namespace AStar.Dev.Infrastructure.FilesDb.Data;

/// <summary>
///
/// </summary>
public static class FileDetailDirectoryNameExtensions
{
/// <summary>
///
/// </summary>
/// <param name="filesContext"></param>
/// <param name="files"></param>
/// <param name="directoryName"></param>
/// <param name="includeSubDirectories"></param>
/// <returns></returns>
public static IQueryable<FileDetail> WhereDirectoryNameMatches(this IQueryable<FileDetail> filesContext, string directoryName, bool includeSubDirectories) =>
public static IQueryable<FileDetail> WhereDirectoryNameMatches(this IQueryable<FileDetail> files, string directoryName, bool includeSubDirectories) =>
includeSubDirectories
? filesContext.Where(file => file.DirectoryName.Value.StartsWith(directoryName.RemoveTrailing(@"\")))
: filesContext.Where(file => file.DirectoryName.Value == directoryName.RemoveTrailing(@"\"));
? files.Where(file => file.DirectoryName.Value.Contains(directoryName.RemoveTrailing(@"\")))
: files.Where(file => file.DirectoryName.Value == directoryName.RemoveTrailing(@"\"));
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,19 @@
namespace AStar.Dev.Infrastructure.FilesDb.Data;

/// <summary>
///
/// </summary>
public static class FileDetailLastViewedExtensions
{
/// <summary>
/// A lot of variations of this method have been tried, but none of them worked as expected.
/// This one does not work as we're using SQLite for testing, and it does not support DateTimeOffset.
/// A lot of variations of this method have been tried, but none of them worked as expected.
/// This one does not work as we're using SQLite for testing, and it does not support DateTimeOffset.
/// </summary>
/// <param name="filesContext"></param>
/// <param name="files"></param>
/// <param name="days"></param>
/// <param name="time"></param>
/// <returns></returns>
public static IQueryable<FileDetail> WhereLastViewedIsOlderThan(this IQueryable<FileDetail> filesContext, int days, TimeProvider time)
public static IQueryable<FileDetail> WhereLastViewedIsOlderThan(this IQueryable<FileDetail> files, int days, TimeProvider time)
=> days == 0
? filesContext
: filesContext.Where(file => !file.FileLastViewed.HasValue || file.FileLastViewed.Value <= time.GetUtcNow().AddDays(-days));
? files
: files.Where(file => !file.FileLastViewed.HasValue || file.FileLastViewed.Value <= time.GetUtcNow().AddDays(-days));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Diagnostics;
using AStar.Dev.Infrastructure.FilesDb.Models;

namespace AStar.Dev.Infrastructure.FilesDb.Data;

/// <summary>
/// </summary>
public static class FileDetailOrderingExtensions
{
/// <summary>
/// </summary>
/// <param name="files"></param>
/// <param name="sortOrder"></param>
/// <returns></returns>
public static IQueryable<FileDetail> OrderResultsBy(this IQueryable<FileDetail> files, SortOrder sortOrder)
=> sortOrder switch
{
SortOrder.NameAscending => files.OrderBy(f => f.FileName.Value),
SortOrder.NameDescending => files.OrderByDescending(f => f.FileName.Value),
SortOrder.SizeAscending => files.OrderBy(f => f.FileSize),
SortOrder.SizeDescending => files.OrderByDescending(f => f.FileSize),
_ => throw new UnreachableException("If we reach here, a new SortOrder has been added but not included...")
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using AStar.Dev.Infrastructure.FilesDb.Models;

namespace AStar.Dev.Infrastructure.FilesDb.Data;

/// <summary>
/// </summary>
public static class FileDetailPagingExtensions
{
/// <summary>
/// </summary>
/// <param name="files"></param>
/// <param name="pageNumber"></param>
/// <param name="pageSize"></param>
/// <returns></returns>
public static IQueryable<FileDetail> GetPage(this IQueryable<FileDetail> files, int pageNumber, int pageSize)
{
pageSize = RestrictPageSize(pageSize);

if (pageNumber < 1)
{
pageNumber = 1;
}

return files.Skip(pageNumber * pageSize).Take(pageSize);
}

private static int RestrictPageSize(int pageSize) =>
pageSize switch
{
< 1 => 1,
> 50 => 50,
_ => pageSize
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Diagnostics;
using AStar.Dev.Infrastructure.FilesDb.Models;

namespace AStar.Dev.Infrastructure.FilesDb.Data;

/// <summary>
/// </summary>
public static class FileDetailSearchTypeExtensions
{
/// <summary>
/// </summary>
/// <param name="files"></param>
/// <param name="searchType"></param>
/// <returns></returns>
public static IQueryable<FileDetail> OfSearchType(this IQueryable<FileDetail> files, SearchType searchType)
=> searchType switch
{
SearchType.All => files,
SearchType.Images => files.Where(f => f.IsImage),
SearchType.Duplicates => files.Where(f => files.Count(x => x.FileSize == f.FileSize) > 1),
SearchType.DuplicateImages => files.Where(f => f.IsImage &&
files.Count(x => x.IsImage &&
x.FileSize == f.FileSize &&
x.ImageDetail.Height == f.ImageDetail.Height &&
x.ImageDetail.Width == f.ImageDetail.Width) > 1),
_ => throw new UnreachableException("If we reach here, a new SearchType has been added but not included...")
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using AStar.Dev.Infrastructure.FilesDb.Models;

namespace AStar.Dev.Infrastructure.FilesDb.Data;

/// <summary>
/// </summary>
public static class FileDetailTextContainsExtensions
{
/// <summary>
/// </summary>
/// <param name="files"></param>
/// <param name="searchText"></param>
/// <returns></returns>
public static IQueryable<FileDetail> SelectFilesMatching(this IQueryable<FileDetail> files, string? searchText)
=> string.IsNullOrEmpty(searchText)
? files
: files.Where(file => file.DirectoryName.Value.Contains(searchText) || file.FileName.Value.Contains(searchText));
}
9 changes: 5 additions & 4 deletions src/AStar.Dev.Infrastructure.FilesDb/Data/FilesContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
_ = modelBuilder.UseCollation("SQL_Latin1_General_CP1_CI_AS");
_ = modelBuilder.HasDefaultSchema(Constants.SchemaName);
_ = modelBuilder.ApplyConfigurationsFromAssembly(typeof(FilesContext).Assembly);

_ = modelBuilder
.Entity<DuplicateDetail>(eb =>
{
eb.HasNoKey();
eb.ToView("vw_DuplicateDetails");
});
{
_ = eb.HasNoKey();
_ = eb.ToView("vw_DuplicateDetails");
});
}
}
Loading
Loading