diff --git a/EFCore.Sqlite.slnf b/EFCore.Sqlite.slnf index 66e5616df2f..1a0652b9655 100644 --- a/EFCore.Sqlite.slnf +++ b/EFCore.Sqlite.slnf @@ -9,7 +9,6 @@ "src\\EFCore.Relational\\EFCore.Relational.csproj", "src\\EFCore.Sqlite.Core\\EFCore.Sqlite.Core.csproj", "src\\EFCore.Sqlite.NTS\\EFCore.Sqlite.NTS.csproj", - "src\\EFCore.Sqlite\\EFCore.Sqlite.csproj", "src\\EFCore\\EFCore.csproj", "src\\Microsoft.Data.Sqlite.Core\\Microsoft.Data.Sqlite.Core.csproj", "test\\EFCore.Analyzers.Tests\\EFCore.Analyzers.Test.csproj", diff --git a/src/EFCore.Relational/Query/QuerySqlGenerator.cs b/src/EFCore.Relational/Query/QuerySqlGenerator.cs index 84bb6ee8ae7..16f4d8c0549 100644 --- a/src/EFCore.Relational/Query/QuerySqlGenerator.cs +++ b/src/EFCore.Relational/Query/QuerySqlGenerator.cs @@ -3,9 +3,7 @@ using System; using System.Collections.Generic; -using System.Data.Common; using System.Diagnostics; -using System.IO; using System.Linq; using System.Linq.Expressions; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; @@ -72,11 +70,6 @@ public virtual IRelationalCommand GetCommand(SelectExpression selectExpression) /// protected virtual string AliasSeparator { get; } = " AS "; - /// - /// The default single line comment prefix. - /// - protected virtual string SingleLineCommentToken { get; } = "--"; - protected virtual IRelationalCommandBuilder Sql => _relationalCommandBuilder; protected virtual void GenerateTagsHeaderComment(SelectExpression selectExpression) @@ -85,16 +78,9 @@ protected virtual void GenerateTagsHeaderComment(SelectExpression selectExpressi { foreach (var tag in selectExpression.Tags) { - using (var reader = new StringReader(tag)) - { - string line; - while ((line = reader.ReadLine()) != null) - { - _relationalCommandBuilder.Append(SingleLineCommentToken).Append(" ").AppendLine(line); - } - } - - _relationalCommandBuilder.AppendLine(); + _relationalCommandBuilder + .AppendLines(_sqlGenerationHelper.GenerateComment(tag)) + .AppendLine(); } } } diff --git a/src/EFCore.Relational/Storage/ISqlGenerationHelper.cs b/src/EFCore.Relational/Storage/ISqlGenerationHelper.cs index a8bd9512dcc..f7774e9ce39 100644 --- a/src/EFCore.Relational/Storage/ISqlGenerationHelper.cs +++ b/src/EFCore.Relational/Storage/ISqlGenerationHelper.cs @@ -33,6 +33,11 @@ public interface ISqlGenerationHelper /// string BatchTerminator { get; } + /// + /// The default single-line comment prefix. + /// + string SingleLineCommentToken { get; } + /// /// Generates a valid parameter name for the given candidate name. /// @@ -98,5 +103,12 @@ public interface ISqlGenerationHelper /// The identifier to delimit. /// The schema of the identifier. void DelimitIdentifier([NotNull] StringBuilder builder, [NotNull] string name, [CanBeNull] string schema); + + /// + /// Generates a SQL comment. + /// + /// The comment text. + /// The generated SQL. + string GenerateComment([NotNull] string text); } } diff --git a/src/EFCore.Relational/Storage/RelationalSqlGenerationHelper.cs b/src/EFCore.Relational/Storage/RelationalSqlGenerationHelper.cs index 98af01b0439..42be1ae1fdb 100644 --- a/src/EFCore.Relational/Storage/RelationalSqlGenerationHelper.cs +++ b/src/EFCore.Relational/Storage/RelationalSqlGenerationHelper.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.IO; using System.Text; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; @@ -43,6 +44,11 @@ public RelationalSqlGenerationHelper([NotNull] RelationalSqlGenerationHelperDepe /// public virtual string BatchTerminator => string.Empty; + /// + /// The default single-line comment prefix. + /// + public virtual string SingleLineCommentToken => "--"; + /// /// Generates a valid parameter name for the given candidate name. /// @@ -159,5 +165,27 @@ public virtual void DelimitIdentifier(StringBuilder builder, string name, string DelimitIdentifier(builder, name); } + + /// + /// Generates a SQL comment. + /// + /// The comment text. + /// The generated SQL. + public virtual string GenerateComment(string text) + { + Check.NotEmpty(text, nameof(text)); + + var builder = new StringBuilder(); + using (var reader = new StringReader(text)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + builder.Append(SingleLineCommentToken).Append(" ").AppendLine(line); + } + } + + return builder.ToString(); + } } } diff --git a/src/EFCore.Sqlite.Core/Migrations/SqliteMigrationsSqlGenerator.cs b/src/EFCore.Sqlite.Core/Migrations/SqliteMigrationsSqlGenerator.cs index fc5179eb7f1..ec84d45732e 100644 --- a/src/EFCore.Sqlite.Core/Migrations/SqliteMigrationsSqlGenerator.cs +++ b/src/EFCore.Sqlite.Core/Migrations/SqliteMigrationsSqlGenerator.cs @@ -358,8 +358,9 @@ protected override void Generate( using (builder.Indent()) { - CreateComment(builder, operation.Comment); - builder.AppendLine(); + builder + .AppendLines(Dependencies.SqlGenerationHelper.GenerateComment(operation.Comment)) + .AppendLine(); CreateTableColumns(operation, model, builder); CreateTableConstraints(operation, model, builder); builder.AppendLine(); @@ -375,6 +376,12 @@ protected override void Generate( } } + /// + /// Generates a SQL fragment for the column definitions in an . + /// + /// The operation. + /// The target model which may be null if the operations exist without a model. + /// The command builder to use to add the SQL fragment. protected override void CreateTableColumns( CreateTableOperation operation, IModel model, @@ -409,7 +416,7 @@ private void CreateTableColumnsWithComments( if (!string.IsNullOrEmpty(column.Comment)) { - CreateComment(builder, column.Comment); + builder.AppendLines(Dependencies.SqlGenerationHelper.GenerateComment(column.Comment)); } ColumnDefinition(column, model, builder); @@ -421,14 +428,6 @@ private void CreateTableColumnsWithComments( } } - private void CreateComment(MigrationCommandListBuilder builder, string comment) - { - foreach (var line in comment.Split(Environment.NewLine).Select(l => $"-- {l}")) - { - builder.AppendLine(line); - } - } - /// /// Generates a SQL fragment for a column definition for the given column metadata. /// diff --git a/test/EFCore.Sqlite.FunctionalTests/SqliteMigrationSqlGeneratorTest.cs b/test/EFCore.Sqlite.FunctionalTests/SqliteMigrationSqlGeneratorTest.cs index 8ec6f1c79c9..087a016c17b 100644 --- a/test/EFCore.Sqlite.FunctionalTests/SqliteMigrationSqlGeneratorTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/SqliteMigrationSqlGeneratorTest.cs @@ -563,56 +563,6 @@ public virtual void CreateTableOperation_has_comment() "); } - [ConditionalFact] - public virtual void CreateTableOperation_no_comments() - { - Generate( - new CreateTableOperation - { - Name = "People", - Columns = - { - new AddColumnOperation - { - Name = "Id", - Table = "People", - ClrType = typeof(int), - IsNullable = false, - }, - new AddColumnOperation - { - Name = "UncommentedColumn1", - Table = "People", - ClrType = typeof(string), - IsNullable = false - }, - new AddColumnOperation - { - Name = "UncommentedColumn2", - Table = "People", - ClrType = typeof(string), - IsNullable = false - }, - new AddColumnOperation - { - Name = "UncommentedName", - Table = "People", - ClrType = typeof(string), - IsNullable = false, - } - } - }); - - AssertSql( - @"CREATE TABLE ""People"" ( - ""Id"" INTEGER NOT NULL, - ""UncommentedColumn1"" TEXT NOT NULL, - ""UncommentedColumn2"" TEXT NOT NULL, - ""UncommentedName"" TEXT NOT NULL -); -"); - } - [ConditionalFact] public virtual void CreateTableOperation_has_multi_line_comment() {