Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrations: Use parameter objects in MigrationsSqlGenerator #15123

Merged
merged 2 commits into from
Mar 22, 2019
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
123 changes: 33 additions & 90 deletions src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Update;
Expand Down Expand Up @@ -1095,10 +1094,7 @@ protected virtual IUpdateSqlGenerator SqlGenerator
=> SequenceOptions(
operation.Schema,
operation.Name,
operation.IncrementBy,
operation.MinValue,
operation.MaxValue,
operation.IsCyclic,
operation,
model,
builder);

Expand All @@ -1115,10 +1111,7 @@ protected virtual IUpdateSqlGenerator SqlGenerator
=> SequenceOptions(
operation.Schema,
operation.Name,
operation.IncrementBy,
operation.MinValue,
operation.MaxValue,
operation.IsCyclic,
operation,
model,
builder);

Expand All @@ -1127,57 +1120,50 @@ protected virtual IUpdateSqlGenerator SqlGenerator
/// </summary>
/// <param name="schema"> The schema that contains the sequence, or <c>null</c> to use the default schema. </param>
/// <param name="name"> The sequence name. </param>
/// <param name="increment"> The amount to increment by to generate the next value in the sequence. </param>
/// <param name="minimumValue"> The minimum value supported by the sequence, or <c>null</c> if none was specified. </param>
/// <param name="maximumValue"> The maximum value supported by the sequence, or <c>null</c> if none was specified. </param>
/// <param name="cycle"> Indicates whether or not the sequence will start again once the maximum value is reached. </param>
/// <param name="operation"> The sequence options. </param>
/// <param name="model"> The target model which may be <c>null</c> if the operations exist without a model. </param>
/// <param name="builder"> The command builder to use to add the SQL fragment. </param>
protected virtual void SequenceOptions(
[CanBeNull] string schema,
[NotNull] string name,
int increment,
long? minimumValue,
long? maximumValue,
bool cycle,
[NotNull] SequenceOperation operation,
[CanBeNull] IModel model,
[NotNull] MigrationCommandListBuilder builder)
{
Check.NotEmpty(name, nameof(name));
Check.NotNull(increment, nameof(increment));
Check.NotNull(cycle, nameof(cycle));
Check.NotNull(operation, nameof(operation));
Check.NotNull(builder, nameof(builder));

var intTypeMapping = Dependencies.TypeMappingSource.GetMapping(typeof(int));
var longTypeMapping = Dependencies.TypeMappingSource.GetMapping(typeof(long));

builder
.Append(" INCREMENT BY ")
.Append(intTypeMapping.GenerateSqlLiteral(increment));
.Append(intTypeMapping.GenerateSqlLiteral(operation.IncrementBy));

if (minimumValue != null)
if (operation.MinValue != null)
{
builder
.Append(" MINVALUE ")
.Append(longTypeMapping.GenerateSqlLiteral(minimumValue));
.Append(longTypeMapping.GenerateSqlLiteral(operation.MinValue));
}
else
{
builder.Append(" NO MINVALUE");
}

if (maximumValue != null)
if (operation.MaxValue != null)
{
builder
.Append(" MAXVALUE ")
.Append(longTypeMapping.GenerateSqlLiteral(maximumValue));
.Append(longTypeMapping.GenerateSqlLiteral(operation.MaxValue));
}
else
{
builder.Append(" NO MAXVALUE");
}

builder.Append(cycle ? " CYCLE" : " NO CYCLE");
builder.Append(operation.IsCyclic ? " CYCLE" : " NO CYCLE");
}

/// <summary>
Expand Down Expand Up @@ -1220,16 +1206,6 @@ protected virtual IUpdateSqlGenerator SqlGenerator
operation.Schema,
operation.Table,
operation.Name,
operation.ClrType,
operation.ColumnType,
operation.IsUnicode,
operation.MaxLength,
operation.IsFixedLength,
operation.IsRowVersion,
operation.IsNullable,
operation.DefaultValue,
operation.DefaultValueSql,
operation.ComputedColumnSql,
operation,
model,
builder);
Expand All @@ -1240,56 +1216,29 @@ protected virtual IUpdateSqlGenerator SqlGenerator
/// <param name="schema"> The schema that contains the table, or <c>null</c> to use the default schema. </param>
/// <param name="table"> The table that contains the column. </param>
/// <param name="name"> The column name. </param>
/// <param name="clrType"> The CLR <see cref="Type" /> that the column is mapped to. </param>
/// <param name="type"> The database/store type for the column, or <c>null</c> if none has been specified. </param>
/// <param name="unicode">
/// Indicates whether or not the column can contain Unicode data, or <c>null</c> if this is not applicable or not specified.
/// </param>
/// <param name="maxLength">
/// The maximum amount of data that the column can contain, or <c>null</c> if this is not applicable or not specified.
/// </param>
/// <param name="fixedLength"> Indicates whether or not the column is constrained to fixed-length data. </param>
/// <param name="rowVersion">
/// Indicates whether or not this column is an automatic concurrency token, such as a SQL Server timestamp/rowversion.
/// </param>
/// <param name="nullable"> Indicates whether or not the column can store <c>NULL</c> values. </param>
/// <param name="defaultValue"> The default value for the column. </param>
/// <param name="defaultValueSql"> The SQL expression to use for the column's default constraint. </param>
/// <param name="computedColumnSql"> The SQL expression to use to compute the column value. </param>
/// <param name="annotatable"> The <see cref="MigrationOperation" /> to use to find any custom annotations. </param>
/// <param name="operation"> The column metadata. </param>
/// <param name="model"> The target model which may be <c>null</c> if the operations exist without a model. </param>
/// <param name="builder"> The command builder to use to add the SQL fragment. </param>
protected virtual void ColumnDefinition(
[CanBeNull] string schema,
[NotNull] string table,
[NotNull] string name,
[NotNull] Type clrType,
[CanBeNull] string type,
bool? unicode,
int? maxLength,
bool? fixedLength,
bool rowVersion,
bool nullable,
[CanBeNull] object defaultValue,
[CanBeNull] string defaultValueSql,
[CanBeNull] string computedColumnSql,
[NotNull] IAnnotatable annotatable,
[NotNull] ColumnOperation operation,
[CanBeNull] IModel model,
[NotNull] MigrationCommandListBuilder builder)
{
Check.NotEmpty(name, nameof(name));
Check.NotNull(clrType, nameof(clrType));
Check.NotNull(annotatable, nameof(annotatable));
Check.NotNull(operation, nameof(operation));
Check.NotNull(builder, nameof(builder));

builder
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(name))
.Append(" ")
.Append(type ?? GetColumnType(schema, table, name, clrType, unicode, maxLength, fixedLength, rowVersion, model));
.Append(operation.ColumnType ?? GetColumnType(schema, table, name, operation, model));

builder.Append(nullable ? " NULL" : " NOT NULL");
builder.Append(operation.IsNullable ? " NULL" : " NOT NULL");

DefaultValue(defaultValue, defaultValueSql, builder);
DefaultValue(operation.DefaultValue, operation.DefaultValueSql, builder);
}

/// <summary>
Expand All @@ -1298,51 +1247,45 @@ protected virtual IUpdateSqlGenerator SqlGenerator
/// <param name="schema"> The schema that contains the table, or <c>null</c> to use the default schema. </param>
/// <param name="table"> The table that contains the column. </param>
/// <param name="name"> The column name. </param>
/// <param name="clrType"> The CLR <see cref="Type" /> that the column is mapped to. </param>
/// <param name="unicode">
/// Indicates whether or not the column can contain Unicode data, or <c>null</c> if this is not applicable or not specified.
/// </param>
/// <param name="maxLength">
/// The maximum amount of data that the column can contain, or <c>null</c> if this is not applicable or not specified.
/// </param>
/// <param name="fixedLength"> Indicates whether or not the data is constrained to fixed-length data. </param>
/// <param name="rowVersion">
/// Indicates whether or not this column is an automatic concurrency token, such as a SQL Server timestamp/rowversion.
/// </param>
/// <param name="operation"> The column metadata. </param>
/// <param name="model"> The target model which may be <c>null</c> if the operations exist without a model. </param>
/// <returns> The database/store type for the column. </returns>
protected virtual string GetColumnType(
[CanBeNull] string schema,
[NotNull] string table,
[NotNull] string name,
[NotNull] Type clrType,
bool? unicode,
int? maxLength,
bool? fixedLength,
bool rowVersion,
[NotNull] ColumnOperation operation,
[CanBeNull] IModel model)
{
Check.NotEmpty(table, nameof(table));
Check.NotEmpty(name, nameof(name));
Check.NotNull(clrType, nameof(clrType));
Check.NotNull(operation, nameof(operation));

var keyOrIndex = false;

var property = FindProperty(model, schema, table, name);
if (property != null)
{
if (unicode == property.IsUnicode()
&& maxLength == property.GetMaxLength()
&& (fixedLength ?? false) == property.Relational().IsFixedLength
&& rowVersion == (property.IsConcurrencyToken && property.ValueGenerated == ValueGenerated.OnAddOrUpdate))
if (operation.IsUnicode == property.IsUnicode()
&& operation.MaxLength == property.GetMaxLength()
&& (operation.IsFixedLength ?? false) == property.Relational().IsFixedLength
&& operation.IsRowVersion == (property.IsConcurrencyToken && property.ValueGenerated == ValueGenerated.OnAddOrUpdate))
{
return Dependencies.TypeMappingSource.FindMapping(property).StoreType;
}

keyOrIndex = property.IsKey() || property.IsForeignKey();
}

return Dependencies.TypeMappingSource.FindMapping(clrType, null, keyOrIndex, unicode, maxLength, rowVersion, fixedLength).StoreType;
return Dependencies.TypeMappingSource.FindMapping(
operation.ClrType,
null,
keyOrIndex,
operation.IsUnicode,
operation.MaxLength,
operation.IsRowVersion,
operation.IsFixedLength)
.StoreType;
}

/// <summary>
Expand Down
Loading