Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
dc4baea
Entity Framework: initial setup
messieurMe Jan 14, 2025
c282719
Ef.Ydb -> EfCore.Ydb
messieurMe Jan 15, 2025
b05d9f7
Merge pull request #1 from messieurMe/entityFramework
KirillKurdyukov Jan 17, 2025
4cbc310
Issue-2: added support for bool, int, uint, byte, sbyte, short, ushor…
messieurMe Jan 15, 2025
4448813
Merge branch 'ydb-platform:main' into main
messieurMe Feb 6, 2025
0071a38
fixed sbyte and utf8 in typeMapping
messieurMe Feb 6, 2025
f823b60
Merge pull request #7 from messieurMe/typemapping-fixes
KirillKurdyukov Feb 8, 2025
2aa7a4d
update _string StringTypeMapping
KirillKurdyukov Feb 9, 2025
25ead1f
Merge pull request #8 from messieurMe/feat-StringTypeMapping
KirillKurdyukov Feb 10, 2025
078117d
Merge branch 'ydb-platform:main' into main
messieurMe Mar 3, 2025
7ec4ef1
initialization of project for specification tests
messieurMe Feb 22, 2025
a7d7b44
fixes
messieurMe Mar 3, 2025
d96f824
implementation of schema generation (without scaffolding) (#10)
messieurMe Mar 7, 2025
27276c6
Added support for serial
messieurMe Feb 28, 2025
826612f
Lock implementation for schema generation
messieurMe Mar 4, 2025
d5b37d7
added support for delete and update queries
messieurMe Mar 2, 2025
43dae8f
Basic tests for update & delete
messieurMe Mar 2, 2025
a807d65
Topic Reader & Writer: update auth token in bidirectional stream. (#278)
KirillKurdyukov Mar 3, 2025
af7649b
feat: impl disposing Writer.cs (#279)
KirillKurdyukov Mar 4, 2025
e3294a9
feat: Impl Reader.AsyncDispose (#280)
KirillKurdyukov Mar 5, 2025
8018005
dev: added `ValueTask<string?> GetAuthInfoAsync()` in ICredentialProv…
KirillKurdyukov Mar 5, 2025
ee029fa
Release v0.15.0
Mar 5, 2025
3914605
dev: ydb topic example & chore changes writer (#282)
KirillKurdyukov Mar 6, 2025
88dfdcd
Release v0.15.1
Mar 6, 2025
4800e27
dev: change drop topic signature (#283)
KirillKurdyukov Mar 7, 2025
91736d1
dev: Added SeqNo to `WriteResult` (#284)
KirillKurdyukov Mar 13, 2025
5702be0
Release v0.15.2
Mar 13, 2025
fb07f74
dev: Added SeqNo to Ydb.Sdk.Services.Topic.Reader.Message (#285)
KirillKurdyukov Mar 13, 2025
801abe5
Release v0.15.3
Mar 13, 2025
9f2a019
More types. Added basic json, decimal, string (alternative for TEXT),…
messieurMe Mar 11, 2025
b19f657
Merge branch 'ydb-platform:main' into main
messieurMe Mar 14, 2025
495f8e7
fixes for tests
messieurMe Mar 15, 2025
88d46b1
Merge branch 'ydb-platform:main' into main
KirillKurdyukov Mar 17, 2025
9486cd8
fix lint.yml
KirillKurdyukov Mar 17, 2025
c59e0a4
fix linters + added primary constructors
KirillKurdyukov Mar 18, 2025
14764da
Moved EfCore.Ydb.FunctionalTests -> test directory
KirillKurdyukov Mar 18, 2025
c19b220
delete unused C340085B-AB9E-484A-B4A5-32131AE
KirillKurdyukov Mar 18, 2025
31757cb
added .editorconfig
KirillKurdyukov Mar 18, 2025
e00b1c0
Merge branch 'ydb-platform:main' into entity-framework-to-upstream
KirillKurdyukov Mar 19, 2025
3f87ec0
fix linter
KirillKurdyukov Mar 19, 2025
3825995
fix linter
KirillKurdyukov Mar 19, 2025
564261e
fix linter
KirillKurdyukov Mar 19, 2025
6658f7c
fix linter
KirillKurdyukov Mar 19, 2025
5c7f139
fix linter
KirillKurdyukov Mar 19, 2025
e7f1a70
fix linter
KirillKurdyukov Mar 19, 2025
54225c0
fix
KirillKurdyukov Mar 19, 2025
31bdcfe
fix linter
KirillKurdyukov Mar 19, 2025
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
1 change: 0 additions & 1 deletion .github/scripts/format-all-dotnet-code.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ set -eu

DIR="$1"
SLN_FILE="$2"
PROFILE="$3"

cd "$DIR"

Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
dotnet-version: 9.0.x
- name: Restore
run: dotnet restore ${{ matrix.source-dir }}${{ matrix.solutionFile }}
- name: Install ReSharper
run: dotnet tool install -g JetBrains.ReSharper.GlobalTools
- name: format all files with auto-formatter
run: bash ./.github/scripts/format-all-dotnet-code.sh ${{ matrix.source-dir }} ${{ matrix.solutionFile }} "Custom Cleanup"
run: bash ./.github/scripts/format-all-dotnet-code.sh ${{ matrix.source-dir }} ${{ matrix.solutionFile }}
- name: Check repository diff
run: bash ./.github/scripts/check-work-copy-equals-to-committed.sh "auto-format broken"

Expand All @@ -48,20 +48,21 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Setup .NET
id: setup-dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
dotnet-version: 9.0.x
- name: Restore
run: dotnet restore ${{ matrix.solutionPath }}
- name: Inspect code
uses: muno92/resharper_inspectcode@v1
with:
solutionPath: ${{ matrix.solutionPath }}
version: 2023.2.1
include: |
**.cs
**.cshtml
minimumReportSeverity: WARNING
dotnetVersion: ${{ steps.setup-dotnet.outputs.dotnet-version }}
ignoreIssueType: |
UnusedField.Compiler,
UnusedVariable.Compiler,
Expand Down
6 changes: 6 additions & 0 deletions src/EfCore.Ydb/src/Abstractions/YdbStringAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using System;

namespace EfCore.Ydb.Abstractions;

[AttributeUsage(AttributeTargets.Property)]
public class YdbStringAttribute : Attribute;
16 changes: 16 additions & 0 deletions src/EfCore.Ydb/src/Design/Internal/YdbDesignTimeServices.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using EfCore.Ydb.Extensions;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.DependencyInjection;

namespace EfCore.Ydb.Design.Internal;

public class YdbDesignTimeServices : IDesignTimeServices
{
public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
{
serviceCollection.AddEntityFrameworkYdb();

new EntityFrameworkRelationalDesignServicesBuilder(serviceCollection)
.TryAddCoreServices();
}
}
14 changes: 14 additions & 0 deletions src/EfCore.Ydb/src/Diagnostics/Internal/YdbCommandInterceptor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Data.Common;
using Microsoft.EntityFrameworkCore.Diagnostics;

namespace EfCore.Ydb.Diagnostics.Internal;

// Temporary for debugging
public class YdbCommandInterceptor : DbCommandInterceptor
{
public override InterceptionResult<DbDataReader> ReaderExecuting(
DbCommand command,
CommandEventData eventData,
InterceptionResult<DbDataReader> result
) => result;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using Microsoft.EntityFrameworkCore.Diagnostics;

namespace EfCore.Ydb.Diagnostics.Internal;

public class YdbLoggingDefinitions : RelationalLoggingDefinitions;
21 changes: 21 additions & 0 deletions src/EfCore.Ydb/src/EfCore.Ydb.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>EfCore.Ydb</RootNamespace>
<Nullable>enable</Nullable>
<PackageId>EfCore.Ydb</PackageId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.0"/>
<PackageReference Include="Ydb.Sdk" Version="0.15.3"/>
</ItemGroup>

<ItemGroup>
<Reference Include="Microsoft.EntityFrameworkCore.Relational">
<HintPath>..\..\..\..\..\.nuget\packages\microsoft.entityframeworkcore.relational\9.0.0\lib\net8.0\Microsoft.EntityFrameworkCore.Relational.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using System.Data.Common;
using EfCore.Ydb.Infrastructure;
using EfCore.Ydb.Infrastructure.Internal;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;

namespace EfCore.Ydb.Extensions;

public static class YdbContextOptionsBuilderExtensions
{
public static DbContextOptionsBuilder UseEfYdb(
this DbContextOptionsBuilder optionsBuilder,
string? connectionString,
Action<YdbDbContextOptionsBuilder>? efYdbOptionsAction = null
)
{
var extension = GetOrCreateExtension(optionsBuilder).WithConnectionString(connectionString);
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);

ConfigureWarnings(optionsBuilder);

efYdbOptionsAction?.Invoke(new YdbDbContextOptionsBuilder(optionsBuilder));
return optionsBuilder;
}

public static DbContextOptionsBuilder UseEfYdb(
this DbContextOptionsBuilder optionsBuilder,
DbConnection connection,
Action<YdbDbContextOptionsBuilder>? efYdbOptionsAction = null
)
{
var extension = GetOrCreateExtension(optionsBuilder).WithConnection(connection);
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);

ConfigureWarnings(optionsBuilder);

efYdbOptionsAction?.Invoke(new YdbDbContextOptionsBuilder(optionsBuilder));
return optionsBuilder;
}

// TODO: Right now there are no arguments for constructor, so probably it's ok
private static YdbOptionsExtension GetOrCreateExtension(DbContextOptionsBuilder options)
=> options.Options.FindExtension<YdbOptionsExtension>() ?? new YdbOptionsExtension();

private static void ConfigureWarnings(DbContextOptionsBuilder optionsBuilder)
{
var coreOptionsExtension = optionsBuilder.Options.FindExtension<CoreOptionsExtension>()
?? new CoreOptionsExtension();

coreOptionsExtension = RelationalOptionsExtension.WithDefaultWarningConfiguration(coreOptionsExtension);
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(coreOptionsExtension);
}
}
61 changes: 61 additions & 0 deletions src/EfCore.Ydb/src/Extensions/YdbServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using EfCore.Ydb.Diagnostics.Internal;
using EfCore.Ydb.Infrastructure;
using EfCore.Ydb.Infrastructure.Internal;
using EfCore.Ydb.Metadata.Conventions;
using EfCore.Ydb.Metadata.Internal;
using EfCore.Ydb.Migrations;
using EfCore.Ydb.Migrations.Internal;
using EfCore.Ydb.Query.Internal;
using EfCore.Ydb.Storage.Internal;
using EfCore.Ydb.Update.Internal;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Update;
using Microsoft.Extensions.DependencyInjection;

namespace EfCore.Ydb.Extensions;

public static class YdbServiceCollectionExtensions
{
public static IServiceCollection AddEntityFrameworkYdb(this IServiceCollection serviceCollection)
{
new EntityFrameworkYdbServicesBuilder(serviceCollection)
.TryAdd<LoggingDefinitions, YdbLoggingDefinitions>()
.TryAdd<IDatabaseProvider, DatabaseProvider<YdbOptionsExtension>>()
.TryAdd<IRelationalTypeMappingSource, YdbTypeMappingSource>()
.TryAdd<ISqlGenerationHelper, YdbSqlGenerationHelper>()
.TryAdd<IRelationalAnnotationProvider, YdbAnnotationProvider>()
.TryAdd<IModelValidator, YdbModelValidator>()
.TryAdd<IProviderConventionSetBuilder, YdbConventionSetBuilder>()
.TryAdd<IUpdateSqlGenerator, YdbUpdateSqlGenerator>()
.TryAdd<IModificationCommandFactory, YdbModificationCommandFactory>()
.TryAdd<IRelationalTransactionFactory, YdbRelationalTransactionFactory>()
.TryAdd<IModificationCommandBatchFactory, YdbModificationCommandBatchFactory>()
.TryAdd<IRelationalConnection>(p => p.GetRequiredService<IYdbRelationalConnection>())
.TryAdd<IMigrationsSqlGenerator, YdbMigrationsSqlGenerator>()
.TryAdd<IRelationalDatabaseCreator, YdbDatabaseCreator>()
.TryAdd<IHistoryRepository, YdbHistoryRepository>()
.TryAdd<IQueryableMethodTranslatingExpressionVisitorFactory,
YdbQueryableMethodTranslatingExpressionVisitorFactory>()
.TryAdd<IMethodCallTranslatorProvider, YdbMethodCallTranslatorProvider>()
.TryAdd<IAggregateMethodCallTranslatorProvider, YdbAggregateMethodCallTranslatorProvider>()
.TryAdd<IMemberTranslatorProvider, YdbMemberTranslatorProvider>()
.TryAdd<IQuerySqlGeneratorFactory, YdbQuerySqlGeneratorFactory>()
.TryAdd<IRelationalSqlTranslatingExpressionVisitorFactory, YdbSqlTranslatingExpressionVisitorFactory>()
.TryAdd<IQueryTranslationPostprocessorFactory, YdbQueryTranslationPostprocessorFactory>()
.TryAdd<IRelationalParameterBasedSqlProcessorFactory, YdbParameterBasedSqlProcessorFactory>()
.TryAdd<ISqlExpressionFactory, YdbSqlExpressionFactory>()
.TryAdd<IQueryCompilationContextFactory, YdbQueryCompilationContextFactory>()
.TryAddProviderSpecificServices(b => b
.TryAddScoped<IYdbRelationalConnection, YdbRelationalConnection>()
.TryAddScoped<IDbCommandInterceptor, YdbCommandInterceptor>())
.TryAddCoreServices();

return serviceCollection;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection;

namespace EfCore.Ydb.Infrastructure;

public class EntityFrameworkYdbServicesBuilder(IServiceCollection serviceCollection)
: EntityFrameworkRelationalServicesBuilder(serviceCollection)
{
// ReSharper disable once CollectionNeverUpdated.Local
#pragma warning disable CA1859
private static readonly IDictionary<Type, ServiceCharacteristics> YdbServices
#pragma warning restore CA1859
= new Dictionary<Type, ServiceCharacteristics>
{
// TODO: Add items if required
};

protected override ServiceCharacteristics GetServiceCharacteristics(Type serviceType)
{
var contains = YdbServices.TryGetValue(serviceType, out var characteristics);
return contains
? characteristics
: base.GetServiceCharacteristics(serviceType);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Microsoft.EntityFrameworkCore.Infrastructure;

namespace EfCore.Ydb.Infrastructure.Internal;

// TODO: Not required for mvp
public class YdbModelValidator(
ModelValidatorDependencies dependencies,
RelationalModelValidatorDependencies relationalDependencies
) : RelationalModelValidator(dependencies, relationalDependencies);
36 changes: 36 additions & 0 deletions src/EfCore.Ydb/src/Infrastructure/Internal/YdbOptionsExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Collections.Generic;
using EfCore.Ydb.Extensions;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection;

namespace EfCore.Ydb.Infrastructure.Internal;

public class YdbOptionsExtension : RelationalOptionsExtension
{
private DbContextOptionsExtensionInfo? _info;

public YdbOptionsExtension()
{
}

protected YdbOptionsExtension(YdbOptionsExtension copyFrom) : base(copyFrom)
{
}

protected override RelationalOptionsExtension Clone()
=> new YdbOptionsExtension(this);

public override void ApplyServices(IServiceCollection services)
=> services.AddEntityFrameworkYdb();

public override DbContextOptionsExtensionInfo Info
=> _info ??= new ExtensionInfo(this);

private sealed class ExtensionInfo(IDbContextOptionsExtension extension) : RelationalExtensionInfo(extension)
{
public override bool IsDatabaseProvider => true;

// TODO: Right now it's stub
public override void PopulateDebugInfo(IDictionary<string, string> debugInfo) => debugInfo["Hello"] = "World!";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using EfCore.Ydb.Infrastructure.Internal;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;

namespace EfCore.Ydb.Infrastructure;

public class YdbDbContextOptionsBuilder(DbContextOptionsBuilder optionsBuilder)
: RelationalDbContextOptionsBuilder<YdbDbContextOptionsBuilder, YdbOptionsExtension>(optionsBuilder);
18 changes: 18 additions & 0 deletions src/EfCore.Ydb/src/Metadata/Conventions/YdbConventionSetBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;

namespace EfCore.Ydb.Metadata.Conventions;

// ReSharper disable once ClassNeverInstantiated.Global
public class YdbConventionSetBuilder(
ProviderConventionSetBuilderDependencies dependencies,
RelationalConventionSetBuilderDependencies relationalDependencies
) : RelationalConventionSetBuilder(dependencies, relationalDependencies)
{
public override ConventionSet CreateConventionSet()
{
var coreConventions = base.CreateConventionSet();
coreConventions.Add(new YdbStringAttributeConvention(Dependencies));
return coreConventions;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Reflection;
using EfCore.Ydb.Abstractions;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;

namespace EfCore.Ydb.Metadata.Conventions;

public class YdbStringAttributeConvention(ProviderConventionSetBuilderDependencies dependencies)
: PropertyAttributeConventionBase<YdbStringAttribute>(dependencies)
{
protected override void ProcessPropertyAdded(
IConventionPropertyBuilder propertyBuilder,
YdbStringAttribute attribute,
MemberInfo clrMember,
IConventionContext context
) => propertyBuilder.HasColumnType("string");
}
8 changes: 8 additions & 0 deletions src/EfCore.Ydb/src/Metadata/Internal/YdbAnnotationNames.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace EfCore.Ydb.Metadata.Internal;

public static class YdbAnnotationNames
{
private const string Prefix = "Ydb";

public const string Serial = Prefix + "Serial";
}
33 changes: 33 additions & 0 deletions src/EfCore.Ydb/src/Metadata/Internal/YdbAnnotationProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;

namespace EfCore.Ydb.Metadata.Internal;

public class YdbAnnotationProvider(RelationalAnnotationProviderDependencies dependencies)
: RelationalAnnotationProvider(dependencies)
{
public override IEnumerable<IAnnotation> For(IColumn column, bool designTime)
{
if (!designTime)
{
yield break;
}

// TODO: Add Yson here too?
if (column is JsonColumn)
{
yield break;
}

var property = column.PropertyMappings[0].Property;

if (property.ValueGenerated == ValueGenerated.OnAdd
&& property.ClrType == typeof(int)
&& property.FindTypeMapping()?.Converter == null)
{
yield return new Annotation(YdbAnnotationNames.Serial, true);
}
}
}
Loading
Loading