Skip to content

Commit

Permalink
Use current DbConnection for updating the sql_mode. (#1862) (#1882)
Browse files Browse the repository at this point in the history
Don't set `sql_mode` for admin/master connections.

(cherry picked from commit 2b0ca14)
  • Loading branch information
lauxjpn committed Mar 16, 2024
1 parent 53826cc commit 73aab49
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 9 deletions.
37 changes: 28 additions & 9 deletions src/EFCore.MySql/Storage/Internal/MySqlRelationalConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ protected static DbDataSource GetEffectiveDataSource(IMySqlOptions mySqlSingleto
=> mySqlSingletonOptions.DataSource ??
contextOptions.FindExtension<CoreOptionsExtension>()?.ApplicationServiceProvider?.GetService<MySqlDataSource>();

// TODO: Remove, because we don't use it anywhere.
private bool IsMasterConnection { get; set; }

protected override DbConnection CreateDbConnection()
Expand Down Expand Up @@ -250,7 +249,9 @@ public override bool Open(bool errorsExpected = false)

if (result)
{
if (_mySqlOptionsExtension.UpdateSqlModeOnOpen && _mySqlOptionsExtension.NoBackslashEscapes)
if (_mySqlOptionsExtension.UpdateSqlModeOnOpen &&
_mySqlOptionsExtension.NoBackslashEscapes &&
!IsMasterConnection)
{
AddSqlMode(NoBackslashEscapes);
}
Expand All @@ -266,9 +267,11 @@ public override async Task<bool> OpenAsync(CancellationToken cancellationToken,

if (result)
{
if (_mySqlOptionsExtension.UpdateSqlModeOnOpen && _mySqlOptionsExtension.NoBackslashEscapes)
if (_mySqlOptionsExtension.UpdateSqlModeOnOpen &&
_mySqlOptionsExtension.NoBackslashEscapes &&
!IsMasterConnection)
{
await AddSqlModeAsync(NoBackslashEscapes)
await AddSqlModeAsync(NoBackslashEscapes, cancellationToken)
.ConfigureAwait(false);
}
}
Expand All @@ -277,16 +280,32 @@ await AddSqlModeAsync(NoBackslashEscapes)
}

public virtual void AddSqlMode(string mode)
=> Dependencies.CurrentContext.Context?.Database.ExecuteSqlInterpolated($@"SET SESSION sql_mode = CONCAT(@@sql_mode, ',', {mode});");
=> ExecuteNonQuery($@"SET SESSION sql_mode = CONCAT(@@sql_mode, ',', '{mode}');");

public virtual Task AddSqlModeAsync(string mode, CancellationToken cancellationToken = default)
=> Dependencies.CurrentContext.Context?.Database.ExecuteSqlInterpolatedAsync($@"SET SESSION sql_mode = CONCAT(@@sql_mode, ',', {mode});", cancellationToken);
=> ExecuteNonQueryAsync($@"SET SESSION sql_mode = CONCAT(@@sql_mode, ',', '{mode}');", cancellationToken);

public virtual void RemoveSqlMode(string mode)
=> Dependencies.CurrentContext.Context?.Database.ExecuteSqlInterpolated($@"SET SESSION sql_mode = REPLACE(@@sql_mode, {mode}, '');");
=> ExecuteNonQuery($@"SET SESSION sql_mode = REPLACE(@@sql_mode, '{mode}', '');");

public virtual void RemoveSqlModeAsync(string mode, CancellationToken cancellationToken = default)
=> Dependencies.CurrentContext.Context?.Database.ExecuteSqlInterpolatedAsync($@"SET SESSION sql_mode = REPLACE(@@sql_mode, {mode}, '');", cancellationToken);
public virtual Task RemoveSqlModeAsync(string mode, CancellationToken cancellationToken = default)
=> ExecuteNonQueryAsync($@"SET SESSION sql_mode = REPLACE(@@sql_mode, '{mode}', '');", cancellationToken);

protected virtual void ExecuteNonQuery(string sql)
{
using var command = DbConnection.CreateCommand();
command.CommandText = sql;
command.ExecuteNonQuery();
}

protected virtual async Task ExecuteNonQueryAsync(string sql, CancellationToken cancellationToken = default)
{
var command = DbConnection.CreateCommand();
await using (command.ConfigureAwait(false))
{
command.CommandText = sql;
await command.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);
}
}
}
}
27 changes: 27 additions & 0 deletions test/EFCore.MySql.FunctionalTests/ConnectionMySqlTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;
using MySqlConnector;
using Pomelo.EntityFrameworkCore.MySql.FunctionalTests.TestUtilities;
Expand Down Expand Up @@ -113,6 +114,32 @@ public void Can_create_admin_connection_with_connection()
masterConnection.Open();
}

[Fact]
public void Can_create_database_with_disablebackslashescaping()
{
var optionsBuilder = new DbContextOptionsBuilder<GeneralOptionsContext>();
optionsBuilder.UseMySql(MySqlTestStore.CreateConnectionString("ConnectionTest_" + Guid.NewGuid()), AppConfig.ServerVersion, b => b.ApplyConfiguration().DisableBackslashEscaping());
using var context = new GeneralOptionsContext(optionsBuilder.Options);

var relationalDatabaseCreator = context.GetService<IRelationalDatabaseCreator>();

try
{
relationalDatabaseCreator.EnsureCreated();
}
finally
{
try
{
relationalDatabaseCreator.EnsureDeleted();
}
catch
{
// ignored
}
}
}

private readonly IServiceProvider _serviceProvider = new ServiceCollection()
.AddEntityFrameworkMySql()
.BuildServiceProvider();
Expand Down

0 comments on commit 73aab49

Please sign in to comment.