Skip to content
Draft
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
6 changes: 6 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ jobs:
with:
dotnet-version: "10.0.x"

- name: Setup .NET 11
uses: actions/setup-dotnet@v4
with:
dotnet-version: "11.0.x"
dotnet-quality: "preview"

- name: Restore dependencies
run: dotnet restore

Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,22 @@ jobs:
with:
dotnet-version: '10.0.x'

- name: Setup .NET 11
uses: actions/setup-dotnet@v4
with:
dotnet-version: '11.0.x'
dotnet-quality: 'preview'

- name: Restore dependencies
run: dotnet restore

- name: Build project
run: dotnet build --no-restore

# Absolute project path: the .NET 11 SDK resolves a relative --project against the
# project directory again for multi-targeted projects (tests/Eftdb.Tests/tests/Eftdb.Tests/...)
- name: Run unit and integration tests with coverage
run: dotnet test --no-build --project tests/Eftdb.Tests -- --coverage --coverage-output-format cobertura --coverage-settings tests/coverage.config --results-directory ./coverage
run: dotnet test --no-build --project ${{ github.workspace }}/tests/Eftdb.Tests/Eftdb.Tests.csproj -- --coverage --coverage-output-format cobertura --coverage-settings tests/coverage.config --results-directory ./coverage

- name: Run functional tests
working-directory: tests/Eftdb.FunctionalTests
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/snapshots.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ jobs:
with:
dotnet-version: "10.0.x"

- name: Setup .NET 11
uses: actions/setup-dotnet@v4
with:
dotnet-version: "11.0.x"
dotnet-quality: "preview"

- name: Restore dependencies
run: dotnet restore

Expand Down
16 changes: 16 additions & 0 deletions src/Eftdb.Design/CompatibilitySuppressions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:CmdScale.EntityFrameworkCore.TimescaleDB.Design.Generators.TimescaleCSharpModelGenerator.#ctor(Microsoft.EntityFrameworkCore.Scaffolding.ModelCodeGeneratorDependencies,Microsoft.EntityFrameworkCore.Design.Internal.IOperationReporter,System.IServiceProvider,Microsoft.EntityFrameworkCore.Design.IAnnotationCodeGenerator)</Target>
<Left>lib/net10.0/CmdScale.EntityFrameworkCore.TimescaleDB.Design.dll</Left>
<Right>lib/net11.0/CmdScale.EntityFrameworkCore.TimescaleDB.Design.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:CmdScale.EntityFrameworkCore.TimescaleDB.Design.Generators.TimescaleDbAnnotationCodeGenerator.#ctor(Microsoft.EntityFrameworkCore.Design.AnnotationCodeGeneratorDependencies,Microsoft.EntityFrameworkCore.Design.Internal.IOperationReporter)</Target>
<Left>lib/net10.0/CmdScale.EntityFrameworkCore.TimescaleDB.Design.dll</Left>
<Right>lib/net11.0/CmdScale.EntityFrameworkCore.TimescaleDB.Design.dll</Right>
</Suppression>
</Suppressions>
7 changes: 5 additions & 2 deletions src/Eftdb.Design/Eftdb.Design.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<TargetFrameworks>net10.0;net11.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>CmdScale.EntityFrameworkCore.TimescaleDB.Design</AssemblyName>
Expand All @@ -23,9 +23,12 @@
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<PackageTags>timescaledb;timescale;efcore;ef-core;entityframeworkcore;postgresql;postgres;time-series;timeseries;data;database;efcore-provider;provider;design;migrations;scaffolding;codegen;cli;tools</PackageTags>
</PropertyGroup>
<ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net10.0'">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.12" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net11.0'">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="11.0.0-rc.3.26522.148" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\assets\cmd-nuget-logo.jpg">
<Pack>True</Pack>
Expand Down
7 changes: 5 additions & 2 deletions src/Eftdb/Eftdb.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<TargetFrameworks>net10.0;net11.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>CmdScale.EntityFrameworkCore.TimescaleDB</AssemblyName>
Expand Down Expand Up @@ -41,7 +41,10 @@
<InternalsVisibleTo Include="CmdScale.EntityFrameworkCore.TimescaleDB.Tests" />
<InternalsVisibleTo Include="CmdScale.EntityFrameworkCore.TimescaleDB.Design" />
</ItemGroup>
<ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net10.0'">
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.3" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net11.0'">
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="11.0.0-rc.3" />
</ItemGroup>
</Project>
13 changes: 12 additions & 1 deletion src/Eftdb/TimescaleDbMigrationsSqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
#if NET11_0_OR_GREATER
using Microsoft.EntityFrameworkCore.Query;
#endif
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal;
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations;

Expand All @@ -15,8 +18,16 @@ namespace CmdScale.EntityFrameworkCore.TimescaleDB
internal class TimescaleDbMigrationsSqlGenerator(
MigrationsSqlGeneratorDependencies dependencies,
INpgsqlSingletonOptions npgsqlSingletonOptions,
#if NET11_0_OR_GREATER
IQuerySqlGeneratorFactory querySqlGeneratorFactory,
#endif
TimescaleDbOptions? timescaleDbOptions = null,
IDiagnosticsLogger<DbLoggerCategory.Migrations>? migrationsLogger = null) : NpgsqlMigrationsSqlGenerator(dependencies, npgsqlSingletonOptions)
IDiagnosticsLogger<DbLoggerCategory.Migrations>? migrationsLogger = null)
#if NET11_0_OR_GREATER
: NpgsqlMigrationsSqlGenerator(dependencies, npgsqlSingletonOptions, querySqlGeneratorFactory)
#else
: NpgsqlMigrationsSqlGenerator(dependencies, npgsqlSingletonOptions)
#endif
{
private static readonly string SkipCommentPrefix = SqlBuilderHelper.SkipComment("Skipping Community Edition feature");

Expand Down
14 changes: 11 additions & 3 deletions tests/Eftdb.Tests/Eftdb.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<TargetFrameworks>net10.0;net11.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>CmdScale.EntityFrameworkCore.TimescaleDB.Tests</AssemblyName>
Expand All @@ -18,14 +18,22 @@
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.9.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="5.9.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="5.9.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.12" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="10.0.3" />
<PackageReference Include="Microsoft.Testing.Extensions.CodeCoverage" Version="18.12.0" />
<PackageReference Include="Moq" Version="4.21.0" />
<PackageReference Include="Testcontainers.PostgreSql" Version="4.15.0" />
<PackageReference Include="xunit.v3" Version="4.0.1" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net10.0'">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.12" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="10.0.3" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net11.0'">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="11.0.0-rc.3.26522.148" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="11.0.0-rc.3" />
</ItemGroup>

<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public async Task Should_Group_And_Aggregate_By_Expressions()
await using ExpressionContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);
DateTime day = new(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc);
await context.Database.ExecuteSqlInterpolatedAsync($"""
await context.Database.ExecuteSqlAsync($"""
INSERT INTO expression_events (occurred_at, actor_id, impersonated_actor_id, action)
VALUES ({day}, {"a"}, NULL, {(short)1}), ({day}, {"a"}, NULL, {(short)1}), ({day}, {"b"}, {"p"}, {(short)4})
""", TestContext.Current.CancellationToken);
Expand Down Expand Up @@ -213,7 +213,7 @@ public async Task Should_Rank_With_Sketches_And_Roll_Them_Up()
await CreateDatabaseViaMigrationAsync(context);
DateTime monday = new(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc);
DateTime tuesday = monday.AddDays(1);
await context.Database.ExecuteSqlInterpolatedAsync($"""
await context.Database.ExecuteSqlAsync($"""
INSERT INTO sketch_events (occurred_at, actor_id)
VALUES ({monday}, {"busy"}), ({monday}, {"busy"}), ({tuesday}, {"busy"}), ({tuesday}, {"quiet"})
""", TestContext.Current.CancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public async Task Should_Create_ContinuousAggregate_With_BasicAggregates()
await using BasicAggregatesContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);

await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO ""Trades"" (""Timestamp"", ""Ticker"", ""Price"", ""Size"", ""Exchange"")
VALUES
({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"AAPL"}, {150.50m}, {100}, {"NYSE"}),
Expand Down Expand Up @@ -183,7 +183,7 @@ public async Task Should_Create_ContinuousAggregate_With_FirstAndLast_Functions(
await using FirstLastContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);

await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO ""Trades"" (""Timestamp"", ""Ticker"", ""Price"", ""Size"", ""Exchange"")
VALUES
({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"AAPL"}, {100.00m}, {100}, {"NYSE"}),
Expand Down Expand Up @@ -260,7 +260,7 @@ public async Task Should_Create_ContinuousAggregate_With_GroupByColumns()
await using GroupByContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);

await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO ""Trades"" (""Timestamp"", ""Ticker"", ""Price"", ""Size"", ""Exchange"")
VALUES
({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"AAPL"}, {100.00m}, {100}, {"NYSE"}),
Expand Down Expand Up @@ -341,7 +341,7 @@ public async Task Should_Create_ContinuousAggregate_With_WhereClause()
await using WhereClauseContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);

await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO ""Trades"" (""Timestamp"", ""Ticker"", ""Price"", ""Size"", ""Exchange"")
VALUES
({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"AAPL"}, {100.00m}, {100}, {"NYSE"}),
Expand Down Expand Up @@ -415,7 +415,7 @@ public async Task Should_Create_ContinuousAggregate_WithNoData_Option()
await using WithNoDataContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);

await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO ""Trades"" (""Timestamp"", ""Ticker"", ""Price"", ""Size"", ""Exchange"")
VALUES ({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"AAPL"}, {100.00m}, {100}, {"NYSE"})", TestContext.Current.CancellationToken);

Expand Down Expand Up @@ -488,7 +488,7 @@ public async Task Should_Create_ContinuousAggregate_With_CustomChunkInterval()
await using CustomChunkIntervalContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);

await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO ""Trades"" (""Timestamp"", ""Ticker"", ""Price"", ""Size"", ""Exchange"")
VALUES
({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"AAPL"}, {150.50m}, {100}, {"NYSE"}),
Expand Down Expand Up @@ -564,7 +564,7 @@ public async Task Should_Create_ContinuousAggregate_With_CreateGroupIndexes()
await using CreateGroupIndexesContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);

await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO ""Trades"" (""Timestamp"", ""Ticker"", ""Price"", ""Size"", ""Exchange"")
VALUES
({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"AAPL"}, {150.50m}, {100}, {"NYSE"}),
Expand Down Expand Up @@ -637,7 +637,7 @@ public async Task Should_Create_ContinuousAggregate_With_MaterializedOnly_False(
await using MaterializedOnlyFalseContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);

await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO ""Trades"" (""Timestamp"", ""Ticker"", ""Price"", ""Size"", ""Exchange"")
VALUES ({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"AAPL"}, {100.00m}, {100}, {"NYSE"})", TestContext.Current.CancellationToken);

Expand Down Expand Up @@ -737,7 +737,7 @@ public async Task Should_Alter_ContinuousAggregate_ChunkInterval()
await using AlterChunkIntervalInitialContext context1 = new(_connectionString!);
await context1.Database.EnsureCreatedAsync(TestContext.Current.CancellationToken);

await context1.Database.ExecuteSqlInterpolatedAsync($@"
await context1.Database.ExecuteSqlAsync($@"
INSERT INTO ""Trades"" (""Timestamp"", ""Ticker"", ""Price"", ""Size"", ""Exchange"")
VALUES
({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"AAPL"}, {150.50m}, {100}, {"NYSE"}),
Expand Down Expand Up @@ -820,7 +820,7 @@ public async Task Should_Alter_ContinuousAggregate_MaterializedOnly()
await using AlterMaterializedOnlyContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);

await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO ""Trades"" (""Timestamp"", ""Ticker"", ""Price"", ""Size"", ""Exchange"")
VALUES
({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"AAPL"}, {150.50m}, {100}, {"NYSE"}),
Expand Down Expand Up @@ -966,7 +966,7 @@ public async Task Should_Drop_ContinuousAggregate_Successfully()
await using DropContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);

await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO ""Trades"" (""Timestamp"", ""Ticker"", ""Price"", ""Size"", ""Exchange"")
VALUES
({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"AAPL"}, {150.50m}, {100}, {"NYSE"}),
Expand Down Expand Up @@ -1045,7 +1045,7 @@ public async Task Should_Generate_Correct_SQL_For_ContinuousAggregate()
await using SqlGenerationContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);

await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO ""Trades"" (""Timestamp"", ""Ticker"", ""Price"", ""Size"", ""Exchange"")
VALUES
({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"AAPL"}, {150.50m}, {100}, {"NYSE"}),
Expand Down Expand Up @@ -1120,7 +1120,7 @@ public async Task Should_Handle_SnakeCase_Naming_Convention()
await using SnakeCaseContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);

await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO trades (timestamp, ticker, price, size, exchange)
VALUES ({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"AAPL"}, {100.00m}, {100}, {"NYSE"})", TestContext.Current.CancellationToken);

Expand Down Expand Up @@ -1189,7 +1189,7 @@ public async Task Should_Create_ContinuousAggregate_With_CountStar_And_Verify_Co
await using CountStarIntegrationContext context = new(_connectionString!);
await CreateDatabaseViaMigrationAsync(context);

await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO count_star_events (""Timestamp"", ""Category"", ""Value"")
VALUES
({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"sports"}, {1.0m}),
Expand Down Expand Up @@ -1462,7 +1462,7 @@ JOIN _timescaledb_catalog.continuous_agg parent
Assert.Contains("hier_chain_1d<-hier_chain_4h", parentLinks);

// Act
await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO hier_chain_raw (""Timestamp"", ""Value"")
VALUES
({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {10.0}),
Expand Down Expand Up @@ -1594,7 +1594,7 @@ FROM timescaledb_information.jobs j
Assert.Contains("hier_combo_daily", policyTargets);

// Act
await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO hier_combo_readings (""Timestamp"", ""MeterId"", ""PowerKw"")
VALUES
({new DateTime(2025, 1, 6, 10, 0, 0, DateTimeKind.Utc)}, {"meter-a"}, {1.0}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ public async Task Should_Execute_Migration_Successfully()
await CreateDatabaseViaMigrationAsync(context);

// Assert
await context.Database.ExecuteSqlInterpolatedAsync($@"
await context.Database.ExecuteSqlAsync($@"
INSERT INTO ""Metrics"" (""Timestamp"", ""Value"")
VALUES ({new DateTime(2025, 1, 1, 10, 0, 0, DateTimeKind.Utc)}, {100.5})
", TestContext.Current.CancellationToken);
Expand Down
Loading
Loading