Skip to content

Commit

Permalink
use EF Migrations in FwLite (#1378)
Browse files Browse the repository at this point in the history
* switch to using migrations with LcmCrdt, auto migrate all projects on startup

* check for pending model changes in fw-lite workflow
  • Loading branch information
hahn-kev authored Jan 15, 2025
1 parent d0e337d commit 481cae7
Show file tree
Hide file tree
Showing 9 changed files with 1,670 additions and 6 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/fw-lite.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version-file: './frontend/package.json'
- name: Install Task
uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 #v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

- name: Set Version
id: setVersion
Expand All @@ -50,6 +54,9 @@ jobs:
echo "VERSION=v$(date --rfc-3339=date)-$shortSha" >> ${GITHUB_OUTPUT}
echo "SEMVER_VERSION=$(date +%Y.%-m.%-d)" >> ${GITHUB_OUTPUT}
- name: Check for pending EF model changes
run: task fw-lite:has-pending-model-changes

- name: Build viewer
working-directory: frontend/viewer
run: |
Expand Down
18 changes: 13 additions & 5 deletions backend/FwLite/FwLiteShared/Sync/BackgroundSyncService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Threading.Channels;
using LcmCrdt;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
Expand Down Expand Up @@ -70,24 +71,31 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
var crdtProjects = crdtProjectsService.ListProjects();
foreach (var crdtProject in crdtProjects)
{
await SyncProject(crdtProject);
await SyncProject(crdtProject, true, stoppingToken);
}

await foreach (var project in _syncResultsChannel.Reader.ReadAllAsync(stoppingToken))
{
//todo, this might not be required, but I can't remember why I added it
await Task.Delay(100, stoppingToken);
await SyncProject(project);
await SyncProject(project, false, stoppingToken);
}
}

private async Task<SyncResults> SyncProject(CrdtProject crdtProject)
private async Task<SyncResults> SyncProject(CrdtProject crdtProject,
bool applyMigrations = false,
CancellationToken cancellationToken = default)
{
try
{
await using var serviceScope = serviceProvider.CreateAsyncScope();
await serviceScope.ServiceProvider.GetRequiredService<CurrentProjectService>().SetupProjectContext(crdtProject);
var syncService = serviceScope.ServiceProvider.GetRequiredService<SyncService>();
var services = serviceScope.ServiceProvider;
await services.GetRequiredService<CurrentProjectService>().SetupProjectContext(crdtProject);
if (applyMigrations)
{
await services.GetRequiredService<LcmCrdtDbContext>().Database.MigrateAsync(cancellationToken);
}
var syncService = services.GetRequiredService<SyncService>();
return await syncService.ExecuteSync();
}
catch (Exception e)
Expand Down
4 changes: 3 additions & 1 deletion backend/FwLite/LcmCrdt/CrdtProjectsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using LcmCrdt.Objects;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations;
using MiniLcm.Project;

namespace LcmCrdt;
Expand Down Expand Up @@ -101,7 +103,7 @@ public async Task<CrdtProject> CreateProject(CreateProjectRequest request)

internal static async Task InitProjectDb(LcmCrdtDbContext db, ProjectData data)
{
await db.Database.EnsureCreatedAsync();
await db.Database.MigrateAsync();
db.ProjectData.Add(data);
await db.SaveChangesAsync();
}
Expand Down
20 changes: 20 additions & 0 deletions backend/FwLite/LcmCrdt/Data/DbContextDesignFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace LcmCrdt.Data;

[Obsolete("this class is only here to facilitate migrations, it's not used in the application", true)]
public class DbContextDesignFactory: IDesignTimeDbContextFactory<LcmCrdtDbContext>
{
public LcmCrdtDbContext CreateDbContext(string[] args)
{
var servicesRoot = new ServiceCollection()
.AddSingleton<IConfiguration>(new ConfigurationRoot([]))
.AddLcmCrdtClient()
.BuildServiceProvider();
var scope = servicesRoot.CreateScope();
scope.ServiceProvider.GetRequiredService<CurrentProjectService>().SetupProjectContextForNewDb(new ("DesignDb", "design.sqlite"));
return scope.ServiceProvider.GetRequiredService<LcmCrdtDbContext>();
}
}
4 changes: 4 additions & 0 deletions backend/FwLite/LcmCrdt/LcmCrdt.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
<PackageReference Include="Humanizer.Core" Version="2.14.1"/>
<PackageReference Include="linq2db.AspNet" Version="5.4.1"/>
<PackageReference Include="linq2db.EntityFrameworkCore" Version="8.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.11">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0"/>
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.0" />
<PackageReference Include="Refit" Version="8.0.0"/>
Expand Down
Loading

0 comments on commit 481cae7

Please sign in to comment.