Skip to content
Closed
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
17 changes: 17 additions & 0 deletions src/EfCore.Ydb/src/Diagnostics/Internal/YdbCommandInterceptor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Data.Common;
using Microsoft.EntityFrameworkCore.Diagnostics;

namespace EfCore.Ydb.Diagnostics.Internal;

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

namespace EfCore.Ydb.Diagnostics.Internal;

public class YdbLoggingDefinitions : RelationalLoggingDefinitions
{
}
24 changes: 24 additions & 0 deletions src/EfCore.Ydb/src/EfCore.Ydb.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<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" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Ydb.Sdk\src\Ydb.Sdk.csproj" />
</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,39 @@
using System;
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;
}

// 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<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 : EntityFrameworkRelationalServicesBuilder
{
private static readonly IDictionary<Type, ServiceCharacteristics> YdbServices
= new Dictionary<Type, ServiceCharacteristics>
{
// TODO: Add items if required
};

public EntityFrameworkYdbServicesBuilder(IServiceCollection serviceCollection) : base(serviceCollection)
{
}

protected override ServiceCharacteristics GetServiceCharacteristics(Type serviceType)
{
var contains = YdbServices.TryGetValue(serviceType, out var characteristics);
return contains
? characteristics
: base.GetServiceCharacteristics(serviceType);
}
}
14 changes: 14 additions & 0 deletions src/EfCore.Ydb/src/Infrastructure/Internal/YdbModelValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Microsoft.EntityFrameworkCore.Infrastructure;

namespace EfCore.Ydb.Infrastructure.Internal;

// TODO: Not required for mvp
public class YdbModelValidator : RelationalModelValidator
{
public YdbModelValidator(
ModelValidatorDependencies dependencies,
RelationalModelValidatorDependencies relationalDependencies
) : base(dependencies, relationalDependencies)
{
}
}
42 changes: 42 additions & 0 deletions src/EfCore.Ydb/src/Infrastructure/Internal/YdbOptionsExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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)
{
private new YdbOptionsExtension Extension
=> (YdbOptionsExtension)base.Extension;

public override bool IsDatabaseProvider => true;

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

namespace EfCore.Ydb.Infrastructure;

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

namespace EfCore.Ydb.Metadata.Conventions;

public class YdbConventionSetBuilder
: RelationalConventionSetBuilder
{
public YdbConventionSetBuilder(
ProviderConventionSetBuilderDependencies dependencies,
RelationalConventionSetBuilderDependencies relationalDependencies
) : base(dependencies, relationalDependencies)
{
}
}
12 changes: 12 additions & 0 deletions src/EfCore.Ydb/src/Metadata/Internal/YdbAnnotationProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Microsoft.EntityFrameworkCore.Metadata;

namespace EfCore.Ydb.Metadata.Internal;

public class YdbAnnotationProvider : RelationalAnnotationProvider
{
public YdbAnnotationProvider(
RelationalAnnotationProviderDependencies dependencies
) : base(dependencies)
{
}
}
55 changes: 55 additions & 0 deletions src/EfCore.Ydb/src/Migrations/Internal/YdbHistoryRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Migrations;

namespace EfCore.Ydb.Migrations.Internal;

// TODO: For migrations only. Not required for mvp
public class YdbHistoryRepository : HistoryRepository
{
public YdbHistoryRepository(
HistoryRepositoryDependencies dependencies
) : base(dependencies)
{
}

protected override bool InterpretExistsResult(object? value)
{
throw new NotImplementedException();
}

public override IMigrationsDatabaseLock AcquireDatabaseLock()
{
throw new NotImplementedException();
}

public override Task<IMigrationsDatabaseLock> AcquireDatabaseLockAsync(
CancellationToken cancellationToken = new CancellationToken())
{
throw new NotImplementedException();
}

public override string GetCreateIfNotExistsScript()
{
throw new NotImplementedException();
}

public override string GetBeginIfNotExistsScript(string migrationId)
{
throw new NotImplementedException();
}

public override string GetBeginIfExistsScript(string migrationId)
{
throw new NotImplementedException();
}

public override string GetEndIfScript()
{
throw new NotImplementedException();
}

public override LockReleaseBehavior LockReleaseBehavior { get; }
protected override string ExistsSql { get; }
}
12 changes: 12 additions & 0 deletions src/EfCore.Ydb/src/Migrations/YdbMigrationsSqlGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Microsoft.EntityFrameworkCore.Migrations;

namespace EfCore.Ydb.Migrations;

public class YdbMigrationsSqlGenerator : MigrationsSqlGenerator
{
public YdbMigrationsSqlGenerator(
MigrationsSqlGeneratorDependencies dependencies
) : base(dependencies)
{
}
}
37 changes: 37 additions & 0 deletions src/EfCore.Ydb/src/Query/Internal/Translators/StubTranslator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;

namespace EfCore.Ydb.Query.Internal.Translators;

// TODO: Remove this class. Temporary stub for debug only
public class StubTranslator : IMethodCallTranslator, IMemberTranslator
{
private readonly YdbSqlExpressionFactory _expressionFactory;

public StubTranslator(
YdbSqlExpressionFactory sqlExpressionFactory)
{
_expressionFactory = sqlExpressionFactory;
}

public SqlExpression? Translate(
SqlExpression? instance,
MethodInfo method,
IReadOnlyList<SqlExpression> arguments,
IDiagnosticsLogger<DbLoggerCategory.Query> logger
)
{
return null;
}

public SqlExpression? Translate(SqlExpression? instance, MemberInfo member, Type returnType,
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
{
return null;
}
}
Loading
Loading