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
3 changes: 3 additions & 0 deletions src/EfCore.Ydb/src/Design/Internal/YdbDesignTimeServices.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using EfCore.Ydb.Extensions;
using EfCore.Ydb.Scaffolding.Internal;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Scaffolding;
using Microsoft.Extensions.DependencyInjection;

namespace EfCore.Ydb.Design.Internal;
Expand All @@ -11,6 +13,7 @@ public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
serviceCollection.AddEntityFrameworkYdb();

new EntityFrameworkRelationalDesignServicesBuilder(serviceCollection)
.TryAdd<IDatabaseModelFactory, YdbDatabaseModelFactory>()
.TryAddCoreServices();
}
}
6 changes: 5 additions & 1 deletion src/EfCore.Ydb/src/EfCore.Ydb.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
<RootNamespace>EfCore.Ydb</RootNamespace>
<Nullable>enable</Nullable>
<PackageId>EfCore.Ydb</PackageId>
<AssemblyName>EfCore.Ydb</AssemblyName>
</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>
<ProjectReference Include="../../Ydb.Sdk/src/Ydb.Sdk.csproj"/>
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ private static readonly IDictionary<Type, ServiceCharacteristics> YdbServices
// 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);
}
protected override ServiceCharacteristics GetServiceCharacteristics(Type serviceType) =>
YdbServices.TryGetValue(serviceType, out var characteristics)
? characteristics
: base.GetServiceCharacteristics(serviceType);
}
208 changes: 172 additions & 36 deletions src/EfCore.Ydb/src/Migrations/YdbMigrationsSqlGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System;
using System.Text;
using EfCore.Ydb.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Ydb.Sdk.Ado;

namespace EfCore.Ydb.Migrations;

Expand Down Expand Up @@ -43,7 +45,7 @@ protected override void Generate(
}

builder.Append(";");
EndStatement(builder, suppressTransaction: true);
EndStatementSuppressTransaction(builder);
}

protected override void ColumnDefinition(
Expand All @@ -69,10 +71,14 @@ MigrationCommandListBuilder builder
};
}

if (operation.ComputedColumnSql is not null)
{
throw new NotSupportedException("Computed/generated columns aren't supported in YDB");
}

builder
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(name))
.Append(DelimitIdentifier(name))
.Append(" ")
// TODO: Add DEFAULT logic somewhere here
.Append(columnType)
.Append(operation.IsNullable ? string.Empty : " NOT NULL");
}
Expand Down Expand Up @@ -120,7 +126,7 @@ protected override void Generate(RenameTableOperation operation, IModel? model,
.Append(" RENAME TO ")
.Append(DelimitIdentifier(operation.NewName, operation.Schema))
.AppendLine(";");
EndStatement(builder);
EndStatementSuppressTransaction(builder);
}

protected override void Generate(
Expand All @@ -140,7 +146,7 @@ protected override void Generate(

if (terminate)
{
EndStatement(builder, suppressTransaction: false);
EndStatement(builder);
}
}

Expand All @@ -156,7 +162,133 @@ protected override void Generate(DeleteDataOperation operation, IModel? model, M
}

builder.Append(sqlBuilder.ToString());
EndStatement(builder, suppressTransaction: false);
EndStatement(builder);
}

protected override void Generate(
DropTableOperation operation,
IModel? model,
MigrationCommandListBuilder builder,
bool terminate = true)
{
builder.Append("DROP TABLE ")
.Append(DelimitIdentifier(operation.Name, operation.Schema));
if (!terminate)
return;
builder.AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator);
EndStatementSuppressTransaction(builder);
}

protected override void Generate(
AddColumnOperation operation,
IModel? model,
MigrationCommandListBuilder builder,
bool terminate = true)
{
if (operation["Relational:ColumnOrder"] != null)
Dependencies.MigrationsLogger.ColumnOrderIgnoredWarning(operation);
builder.Append("ALTER TABLE ")
.Append(DelimitIdentifier(operation.Table, operation.Schema))
.Append(" ADD ");
ColumnDefinition(operation, model, builder);
if (!terminate)
return;
builder.AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator);
EndStatementSuppressTransaction(builder);
}

protected override void Generate(
DropColumnOperation operation,
IModel? model,
MigrationCommandListBuilder builder,
bool terminate = true)
{
builder.Append("ALTER TABLE ")
.Append(DelimitIdentifier(operation.Table, operation.Schema))
.Append(" DROP COLUMN ")
.Append(DelimitIdentifier(operation.Name));

if (!terminate)
return;
builder.AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator);
EndStatementSuppressTransaction(builder);
}

protected override void Generate(
CreateIndexOperation operation,
IModel? model,
MigrationCommandListBuilder builder,
bool terminate = true
)
{
builder.Append("ALTER TABLE ")
.Append(DelimitIdentifier(operation.Table, operation.Schema))
.Append(" ADD INDEX ")
.Append(DelimitIdentifier(operation.Name))
.Append(" GLOBAL ");

// if (operation.IsUnique)
// {
// builder.Append("UNIQUE ");
// }

if (operation.IsDescending != null)
{
throw new NotSupportedException("Descending columns in the index aren't supported in YDB");
}

builder.Append("SYNC ON (")
.Append(ColumnList(operation.Columns))
.Append(")");

if (!terminate)
return;
builder.AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator);
EndStatementSuppressTransaction(builder);
}

protected override void Generate(
DropIndexOperation operation,
IModel? model,
MigrationCommandListBuilder builder,
bool terminate = true)
{
if (operation.Table == null)
{
throw new YdbException("Table name must be specified for DROP INDEX in YDB");
}

builder.Append("ALTER TABLE ")
.Append(DelimitIdentifier(operation.Table, operation.Schema))
.Append(" DROP INDEX ")
.Append(DelimitIdentifier(operation.Name));

if (!terminate)
return;
builder.AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator);
EndStatementSuppressTransaction(builder);
}

protected override void Generate(
RenameIndexOperation operation,
IModel? model,
MigrationCommandListBuilder builder
)
{
if (operation.Table == null)
{
throw new YdbException("Table name must be specified for RENAME INDEX in YDB");
}

builder.Append("ALTER TABLE ")
.Append(DelimitIdentifier(operation.Table, operation.Schema))
.Append(" RENAME INDEX ")
.Append(DelimitIdentifier(operation.Name))
.Append(" TO ")
.Append(DelimitIdentifier(operation.NewName));

builder.AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator);
EndStatementSuppressTransaction(builder);
}

protected override void Generate(UpdateDataOperation operation, IModel? model, MigrationCommandListBuilder builder)
Expand All @@ -171,9 +303,30 @@ protected override void Generate(UpdateDataOperation operation, IModel? model, M
}

builder.Append(sqlBuilder.ToString());
EndStatement(builder, suppressTransaction: false);
EndStatement(builder);
}

protected override void Generate(
DropUniqueConstraintOperation operation,
IModel? model,
MigrationCommandListBuilder builder
)
{
builder.Append("ALTER TABLE ")
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Table, operation.Schema))
.Append(" DROP INDEX ")
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name))
.AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator);

EndStatementSuppressTransaction(builder);
}

protected override void Generate(
DropCheckConstraintOperation operation,
IModel? model,
MigrationCommandListBuilder builder
) => throw new NotSupportedException("Drop check constraint isn't supported in YDB");

protected override void Generate(
DropForeignKeyOperation operation,
IModel? model,
Expand Down Expand Up @@ -231,37 +384,20 @@ protected override void ForeignKeyConstraint(AddForeignKeyOperation operation, I
// Same comment about Foreign keys
}

protected override void CreateTableUniqueConstraints(CreateTableOperation operation, IModel? model,
MigrationCommandListBuilder builder)
{
// We don't have unique constraints
}

protected override void UniqueConstraint(AddUniqueConstraintOperation operation, IModel? model,
MigrationCommandListBuilder builder)
{
// Same comment about Unique constraints
}

protected override void Generate(
CreateIndexOperation operation,
protected override void UniqueConstraint(
AddUniqueConstraintOperation operation,
IModel? model,
MigrationCommandListBuilder builder,
bool terminate = true
)
{
// TODO: We do have Indexes!
// But they're not implemented yet. Ignoring indexes because otherwise table generation during tests will fail
}

MigrationCommandListBuilder builder
) => builder
.Append("INDEX ")
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Name))
.Append(" GLOBAL UNIQUE SYNC ON (")
.Append(ColumnList(operation.Columns))
.Append(")");

// ReSharper disable once RedundantOverriddenMember
protected override void EndStatement(
MigrationCommandListBuilder builder,
// ReSharper disable once OptionalParameterHierarchyMismatch
bool suppressTransaction = true
) => base.EndStatement(builder, suppressTransaction);
private void EndStatementSuppressTransaction(MigrationCommandListBuilder builder) =>
base.EndStatement(builder, true);

private string DelimitIdentifier(string name, string? schema)
private string DelimitIdentifier(string name, string? schema = null)
=> Dependencies.SqlGenerationHelper.DelimitIdentifier(name, schema);
}
Loading
Loading