Skip to content

Commit

Permalink
Update to .NET 6 Preview 7.
Browse files Browse the repository at this point in the history
Update MySqlBatch to inherit from the new DbBatch abstract base class. Fixes #650
  • Loading branch information
bgrainger committed Aug 12, 2021
1 parent d8b9525 commit ffda189
Show file tree
Hide file tree
Showing 12 changed files with 243 additions and 92 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- name: Set up .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.100-preview.6.21355.2
dotnet-version: 6.0.100-preview.7.21379.14

- name: Initialize CodeQL
uses: github/codeql-action/init@v1
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Set up .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.100-preview.6.21355.2
dotnet-version: 6.0.100-preview.7.21379.14

- name: Restore
run: dotnet restore
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
- name: Set up .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.100-preview.6.21355.2
dotnet-version: 6.0.100-preview.7.21379.14
- name: Restore Packages
run: dotnet restore
- name: Build and analyze
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ install:
- ps: Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "install-dotnet.ps1"
- ps: .\install-dotnet.ps1 -Version 3.1.410 -InstallDir "dotnetcli"
- ps: .\install-dotnet.ps1 -Version 5.0.301 -InstallDir "dotnetcli"
- ps: .\install-dotnet.ps1 -Version 6.0.100-preview.6.21355.2 -InstallDir "dotnetcli"
- ps: .\install-dotnet.ps1 -Version 6.0.100-preview.7.21379.14 -InstallDir "dotnetcli"
build_script:
- dotnet --info
before_test:
Expand Down
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
variables:
DotNetCoreSdkVersion: '6.0.100-preview.6.21355.2'
DotNetCoreSdkVersion: '6.0.100-preview.7.21379.14'
NUGET_PACKAGES: '$(Pipeline.Workspace)/.nuget/packages'

jobs:
Expand Down
130 changes: 105 additions & 25 deletions src/MySqlConnector/MySqlBatch.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Data;
using System.Data.Common;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -53,7 +54,11 @@ namespace MySqlConnector
/// </code>
/// </summary>
/// <remarks>The proposed ADO.NET API that <see cref="MySqlBatch"/> is based on is not finalized. This API is experimental and may change in the future.</remarks>
public sealed class MySqlBatch : ICancellableCommand, IDisposable
public sealed class MySqlBatch :
#if NET6_0_OR_GREATER
DbBatch,
#endif
ICancellableCommand, IDisposable
{
/// <summary>
/// Initializes a new <see cref="MySqlBatch"/> object. The <see cref="Connection"/> property must be set before this object can be used.
Expand All @@ -76,20 +81,37 @@ public MySqlBatch(MySqlConnection? connection = null, MySqlTransaction? transact
m_commandId = ICancellableCommandExtensions.GetNextId();
}

#if NET6_0_OR_GREATER
public new MySqlConnection? Connection { get; set; }
protected override DbConnection? DbConnection { get => Connection; set => Connection = (MySqlConnection?) value; }
public new MySqlTransaction? Transaction { get; set; }
protected override DbTransaction? DbTransaction { get => Transaction; set => Transaction = (MySqlTransaction?) value; }
#else
public MySqlConnection? Connection { get; set; }
public MySqlTransaction? Transaction { get; set; }
#endif

/// <summary>
/// The collection of commands that will be executed in the batch.
/// </summary>
#if NET6_0_OR_GREATER
public new MySqlBatchCommandCollection BatchCommands { get; }
protected override DbBatchCommandCollection DbBatchCommands => BatchCommands;
#else
public MySqlBatchCommandCollection BatchCommands { get; }
#endif

/// <summary>
/// Executes all the commands in the batch, returning a <see cref="MySqlDataReader"/> that can iterate
/// over the result sets. If multiple resultsets are returned, use <see cref="MySqlDataReader.NextResult"/>
/// to access them.
/// </summary>
public MySqlDataReader ExecuteReader() => ExecuteDbDataReader();
#if NET6_0_OR_GREATER
public new MySqlDataReader ExecuteReader(CommandBehavior commandBehavior = CommandBehavior.Default) =>
#else
public MySqlDataReader ExecuteReader(CommandBehavior commandBehavior = CommandBehavior.Default) =>
#endif
(MySqlDataReader) ExecuteDbDataReader(commandBehavior);

/// <summary>
/// Executes all the commands in the batch, returning a <see cref="MySqlDataReader"/> that can iterate
Expand All @@ -98,15 +120,30 @@ public MySqlBatch(MySqlConnection? connection = null, MySqlTransaction? transact
/// </summary>
/// <param name="cancellationToken">A token to cancel the asynchronous operation.</param>
/// <returns>A <see cref="Task{MySqlDataReader}"/> containing the result of the asynchronous operation.</returns>
public Task<MySqlDataReader> ExecuteReaderAsync(CancellationToken cancellationToken = default) => ExecuteDbDataReaderAsync(cancellationToken);

private MySqlDataReader ExecuteDbDataReader()
#if NET6_0_OR_GREATER
public new async Task<MySqlDataReader> ExecuteReaderAsync(CancellationToken cancellationToken = default) =>
#else
public async Task<MySqlDataReader> ExecuteReaderAsync(CancellationToken cancellationToken = default) =>
#endif
(MySqlDataReader) await ExecuteDbDataReaderAsync(CommandBehavior.Default, cancellationToken);

// TODO: new ExecuteReaderAsync(CommandBehavior)

#if NET6_0_OR_GREATER
protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
#else
private DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
#endif
{
((ICancellableCommand) this).ResetCommandTimeout();
return ExecuteReaderAsync(IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();
}

private async Task<MySqlDataReader> ExecuteDbDataReaderAsync(CancellationToken cancellationToken)
#if NET6_0_OR_GREATER
protected override async Task<DbDataReader> ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
#else
private async Task<DbDataReader> ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
#endif
{
((ICancellableCommand) this).ResetCommandTimeout();
using var registration = ((ICancellableCommand) this).RegisterCancel(cancellationToken);
Expand All @@ -118,26 +155,54 @@ private Task<MySqlDataReader> ExecuteReaderAsync(IOBehavior ioBehavior, Cancella
if (!IsValid(out var exception))
return Utility.TaskFromException<MySqlDataReader>(exception);

foreach (var batchCommand in BatchCommands)
foreach (MySqlBatchCommand batchCommand in BatchCommands)
batchCommand.Batch = this;

var payloadCreator = Connection!.Session.SupportsComMulti ? BatchedCommandPayloadCreator.Instance :
IsPrepared ? SingleCommandPayloadCreator.Instance :
ConcatenatedCommandPayloadCreator.Instance;
return CommandExecutor.ExecuteReaderAsync(BatchCommands!, payloadCreator, CommandBehavior.Default, ioBehavior, cancellationToken);
return CommandExecutor.ExecuteReaderAsync(BatchCommands!.Commands, payloadCreator, CommandBehavior.Default, ioBehavior, cancellationToken);
}

public int ExecuteNonQuery() => ExecuteNonQueryAsync(IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();

public object ExecuteScalar() => ExecuteScalarAsync(IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();

public Task<int> ExecuteNonQueryAsync(CancellationToken cancellationToken = default) => ExecuteNonQueryAsync(AsyncIOBehavior, cancellationToken);

public Task<object> ExecuteScalarAsync(CancellationToken cancellationToken = default) => ExecuteScalarAsync(AsyncIOBehavior, cancellationToken);

#if NET6_0_OR_GREATER
public override int ExecuteNonQuery() =>
#else
public int ExecuteNonQuery() =>
#endif
ExecuteNonQueryAsync(IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();

#if NET6_0_OR_GREATER
public override object? ExecuteScalar() =>
#else
public object? ExecuteScalar() =>
#endif
ExecuteScalarAsync(IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();

#if NET6_0_OR_GREATER
public override Task<int> ExecuteNonQueryAsync(CancellationToken cancellationToken = default) =>
#else
public Task<int> ExecuteNonQueryAsync(CancellationToken cancellationToken = default) =>
#endif
ExecuteNonQueryAsync(AsyncIOBehavior, cancellationToken);

#if NET6_0_OR_GREATER
public override Task<object?> ExecuteScalarAsync(CancellationToken cancellationToken = default) =>
#else
public Task<object?> ExecuteScalarAsync(CancellationToken cancellationToken = default) =>
#endif
ExecuteScalarAsync(AsyncIOBehavior, cancellationToken);

#if NET6_0_OR_GREATER
public override int Timeout { get; set; }
#else
public int Timeout { get; set; }
#endif

#if NET6_0_OR_GREATER
public override void Prepare()
#else
public void Prepare()
#endif
{
if (!NeedsPrepare(out var exception))
{
Expand All @@ -149,11 +214,29 @@ public void Prepare()
DoPrepareAsync(IOBehavior.Synchronous, default).GetAwaiter().GetResult();
}

public Task PrepareAsync(CancellationToken cancellationToken = default) => PrepareAsync(AsyncIOBehavior, cancellationToken);

public void Cancel() => Connection?.Cancel(this, m_commandId, true);

#if NET6_0_OR_GREATER
public override Task PrepareAsync(CancellationToken cancellationToken = default) =>
#else
public Task PrepareAsync(CancellationToken cancellationToken = default) =>
#endif
PrepareAsync(AsyncIOBehavior, cancellationToken);

#if NET6_0_OR_GREATER
public override void Cancel() =>
#else
public void Cancel() =>
#endif
Connection?.Cancel(this, m_commandId, true);

#if NET6_0_OR_GREATER
protected override DbBatchCommand CreateDbBatchCommand() => new MySqlBatchCommand();
#endif

#if NET6_0_OR_GREATER
public override void Dispose()
#else
public void Dispose()
#endif
{
m_isDisposed = true;
}
Expand Down Expand Up @@ -207,7 +290,7 @@ private async Task<int> ExecuteNonQueryAsync(IOBehavior ioBehavior, Cancellation
return reader.RecordsAffected;
}

private async Task<object> ExecuteScalarAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
private async Task<object?> ExecuteScalarAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
{
((ICancellableCommand) this).ResetCommandTimeout();
using var registration = ((ICancellableCommand) this).RegisterCancel(cancellationToken);
Expand All @@ -224,7 +307,7 @@ private async Task<object> ExecuteScalarAsync(IOBehavior ioBehavior, Cancellatio
hasSetResult = true;
}
} while (await reader.NextResultAsync(ioBehavior, cancellationToken).ConfigureAwait(false));
return result!;
return result;
}

private bool IsValid([NotNullWhen(false)] out Exception? exception)
Expand All @@ -248,7 +331,6 @@ private bool IsValid([NotNullWhen(false)] out Exception? exception)

private bool NeedsPrepare(out Exception? exception)
{
exception = null;
if (m_isDisposed)
exception = new ObjectDisposedException(GetType().Name);
else if (Connection is null)
Expand All @@ -271,8 +353,6 @@ private bool NeedsPrepare(out Exception? exception)
{
if (command is null)
return new InvalidOperationException("BatchCommands must not contain null");
if ((command.CommandBehavior & CommandBehavior.CloseConnection) != 0)
return new NotSupportedException("CommandBehavior.CloseConnection is not supported by MySqlBatch");
if (string.IsNullOrWhiteSpace(command.CommandText))
return new InvalidOperationException("CommandText must be specified on each batch command");
}
Expand Down
40 changes: 34 additions & 6 deletions src/MySqlConnector/MySqlBatchCommand.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
using System.Data;
using System.Data.Common;
using MySqlConnector.Core;

namespace MySqlConnector
{
public sealed class MySqlBatchCommand : IMySqlCommand
public sealed class MySqlBatchCommand :
#if NET6_0_OR_GREATER
DbBatchCommand,
#endif
IMySqlCommand
{
public MySqlBatchCommand()
: this(null)
Expand All @@ -12,19 +17,42 @@ public MySqlBatchCommand()

public MySqlBatchCommand(string? commandText)
{
CommandText = commandText;
CommandText = commandText ?? "";
CommandType = CommandType.Text;
}

public string? CommandText { get; set; }
#if NET6_0_OR_GREATER
public override string CommandText { get; set; }
#else
public string CommandText { get; set; }
#endif
#if NET6_0_OR_GREATER
public override CommandType CommandType { get; set; }
#else
public CommandType CommandType { get; set; }
public CommandBehavior CommandBehavior { get; set; }
public int RecordsAffected { get; set; }
#endif
#if NET6_0_OR_GREATER
public override int RecordsAffected =>
#else
public int RecordsAffected =>
#endif
0;

public MySqlParameterCollection Parameters => m_parameterCollection ??= new();
#if NET6_0_OR_GREATER
public new MySqlParameterCollection Parameters =>
#else
public MySqlParameterCollection Parameters =>
#endif
m_parameterCollection ??= new();

#if NET6_0_OR_GREATER
protected override DbParameterCollection DbParameterCollection => Parameters;
#endif

bool IMySqlCommand.AllowUserVariables => false;

CommandBehavior IMySqlCommand.CommandBehavior => CommandBehavior.Default;

MySqlParameterCollection? IMySqlCommand.RawParameters => m_parameterCollection;

MySqlConnection? IMySqlCommand.Connection => Batch?.Connection;
Expand Down
Loading

0 comments on commit ffda189

Please sign in to comment.