Cleanup code, remove dummy transaction and add missing Dispose() method to JetCommand.

pull/41/head
Lau 6 years ago
parent a71fcc1b69
commit b117d4ea4a

@ -15,9 +15,7 @@ namespace EntityFrameworkCore.Jet.Utilities
[ContractAnnotation("value:null => halt")] [ContractAnnotation("value:null => halt")]
public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName] [NotNull] string parameterName) public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName] [NotNull] string parameterName)
{ {
#pragma warning disable IDE0041 // Use 'is null' check if (value is null)
if (ReferenceEquals(value, null))
#pragma warning restore IDE0041 // Use 'is null' check
{ {
NotEmpty(parameterName, nameof(parameterName)); NotEmpty(parameterName, nameof(parameterName));

@ -71,6 +71,14 @@ namespace System.Data.Jet
this.Transaction = transaction; this.Transaction = transaction;
} }
protected override void Dispose(bool disposing)
{
if (disposing)
_WrappedCommand.Dispose();
base.Dispose(disposing);
}
/// <summary> /// <summary>
/// Attempts to Cancels the command execution /// Attempts to Cancels the command execution
/// </summary> /// </summary>
@ -87,14 +95,8 @@ namespace System.Data.Jet
/// </value> /// </value>
public override string CommandText public override string CommandText
{ {
get get { return this._WrappedCommand.CommandText; }
{ set { this._WrappedCommand.CommandText = value; }
return this._WrappedCommand.CommandText;
}
set
{
this._WrappedCommand.CommandText = value;
}
} }
/// <summary> /// <summary>
@ -105,14 +107,8 @@ namespace System.Data.Jet
/// </value> /// </value>
public override int CommandTimeout public override int CommandTimeout
{ {
get get { return this._WrappedCommand.CommandTimeout; }
{ set { this._WrappedCommand.CommandTimeout = value; }
return this._WrappedCommand.CommandTimeout;
}
set
{
this._WrappedCommand.CommandTimeout = value;
}
} }
/// <summary> /// <summary>
@ -123,14 +119,8 @@ namespace System.Data.Jet
/// </value> /// </value>
public override CommandType CommandType public override CommandType CommandType
{ {
get get { return this._WrappedCommand.CommandType; }
{ set { this._WrappedCommand.CommandType = value; }
return this._WrappedCommand.CommandType;
}
set
{
this._WrappedCommand.CommandType = value;
}
} }
/// <summary> /// <summary>
@ -150,10 +140,7 @@ namespace System.Data.Jet
/// </value> /// </value>
protected override DbConnection DbConnection protected override DbConnection DbConnection
{ {
get get { return this._Connection; }
{
return this._Connection;
}
set set
{ {
if (value == null) if (value == null)
@ -165,7 +152,7 @@ namespace System.Data.Jet
if (!typeof(JetConnection).IsAssignableFrom(value.GetType())) if (!typeof(JetConnection).IsAssignableFrom(value.GetType()))
throw new InvalidOperationException("The JetCommand connection should be a JetConnection"); throw new InvalidOperationException("The JetCommand connection should be a JetConnection");
this._Connection = (JetConnection)value; this._Connection = (JetConnection) value;
} }
} }
} }
@ -189,14 +176,8 @@ namespace System.Data.Jet
/// </value> /// </value>
protected override DbTransaction DbTransaction protected override DbTransaction DbTransaction
{ {
get get { return _Transaction; }
{ set { _Transaction = (JetTransaction) value; }
return _Transaction;
}
set
{
_Transaction = (JetTransaction)value;
}
} }
/// <summary> /// <summary>
@ -207,15 +188,10 @@ namespace System.Data.Jet
/// </value> /// </value>
public override bool DesignTimeVisible public override bool DesignTimeVisible
{ {
get get { return this._DesignTimeVisible; }
{ set { this._DesignTimeVisible = value; }
return this._DesignTimeVisible;
}
set
{
this._DesignTimeVisible = value;
}
} }
/// <summary> /// <summary>
/// Executes the database data reader. /// Executes the database data reader.
/// </summary> /// </summary>
@ -230,7 +206,7 @@ namespace System.Data.Jet
throw new InvalidOperationException(Messages.CannotCallMethodInThisConnectionState("ExecuteReader", ConnectionState.Open, Connection.State)); throw new InvalidOperationException(Messages.CannotCallMethodInThisConnectionState("ExecuteReader", ConnectionState.Open, Connection.State));
_WrappedCommand.Connection = _Connection.InnerConnection; _WrappedCommand.Connection = _Connection.InnerConnection;
// OLE DB forces us to use an existing active transaction, if one is available. // OLE DB forces us to use an existing active transaction, if one is available.
_WrappedCommand.Transaction = _Transaction?.WrappedTransaction ?? _Connection.ActiveTransaction?.WrappedTransaction; _WrappedCommand.Transaction = _Transaction?.WrappedTransaction ?? _Connection.ActiveTransaction?.WrappedTransaction;
@ -264,7 +240,8 @@ namespace System.Data.Jet
private DbDataReader TryGetDataReaderForSelectRowCount(string commandText) private DbDataReader TryGetDataReaderForSelectRowCount(string commandText)
{ {
if (_selectRowCountRegularExpression.Match(commandText).Success) if (_selectRowCountRegularExpression.Match(commandText)
.Success)
{ {
if (_rowCount == null) if (_rowCount == null)
throw new InvalidOperationException("Invalid " + commandText + ". Run a DataReader before."); throw new InvalidOperationException("Invalid " + commandText + ". Run a DataReader before.");
@ -310,13 +287,15 @@ namespace System.Data.Jet
for (int i = 0; i < commandTextList.Length; i++) for (int i = 0; i < commandTextList.Length; i++)
{ {
string commandText = commandTextList[i]; string commandText = commandTextList[i];
if (_selectRowCountRegularExpression.Match(commandText).Success) if (_selectRowCountRegularExpression.Match(commandText)
.Success)
{ {
if (_rowCount == null) if (_rowCount == null)
throw new InvalidOperationException("Invalid " + commandText + ". Run a DataReader before."); throw new InvalidOperationException("Invalid " + commandText + ". Run a DataReader before.");
returnValue = _rowCount.Value; returnValue = _rowCount.Value;
continue; continue;
} }
commandText = ParseIdentity(commandText); commandText = ParseIdentity(commandText);
commandText = ParseGuid(commandText); commandText = ParseGuid(commandText);
@ -338,7 +317,6 @@ namespace System.Data.Jet
if (Connection.State != ConnectionState.Open) if (Connection.State != ConnectionState.Open)
throw new InvalidOperationException(Messages.CannotCallMethodInThisConnectionState(nameof(ExecuteScalar), ConnectionState.Open, Connection.State)); throw new InvalidOperationException(Messages.CannotCallMethodInThisConnectionState(nameof(ExecuteScalar), ConnectionState.Open, Connection.State));
_WrappedCommand.Connection = _Connection.InnerConnection; _WrappedCommand.Connection = _Connection.InnerConnection;
// OLE DB forces us to use an existing active transaction, if one is available. // OLE DB forces us to use an existing active transaction, if one is available.
@ -363,8 +341,6 @@ namespace System.Data.Jet
return this._WrappedCommand.ExecuteScalar(); return this._WrappedCommand.ExecuteScalar();
} }
private JetDataReader InternalExecuteDbDataReader(string commandText, CommandBehavior behavior) private JetDataReader InternalExecuteDbDataReader(string commandText, CommandBehavior behavior)
{ {
int topCount; int topCount;
@ -375,13 +351,16 @@ namespace System.Data.Jet
FixParameters(_WrappedCommand.Parameters); FixParameters(_WrappedCommand.Parameters);
DbCommand command; DbCommand command;
command = (DbCommand)((ICloneable)this._WrappedCommand).Clone(); command = (DbCommand) ((ICloneable) this._WrappedCommand).Clone();
command.CommandText = newCommandText; command.CommandText = newCommandText;
JetDataReader dataReader; JetDataReader dataReader;
if (skipCount != 0) if (skipCount != 0)
dataReader = new JetDataReader(command.ExecuteReader(behavior), topCount == -1 ? 0 : topCount - skipCount, skipCount); dataReader = new JetDataReader(
command.ExecuteReader(behavior), topCount == -1
? 0
: topCount - skipCount, skipCount);
else if (topCount >= 0) else if (topCount >= 0)
dataReader = new JetDataReader(command.ExecuteReader(behavior), topCount, 0); dataReader = new JetDataReader(command.ExecuteReader(behavior), topCount, 0);
else else
@ -394,7 +373,6 @@ namespace System.Data.Jet
private int InternalExecuteNonQuery(string commandText) private int InternalExecuteNonQuery(string commandText)
{ {
// ReSharper disable NotAccessedVariable // ReSharper disable NotAccessedVariable
int topCount; int topCount;
int skipCount; int skipCount;
@ -408,13 +386,12 @@ namespace System.Data.Jet
FixParameters(_WrappedCommand.Parameters); FixParameters(_WrappedCommand.Parameters);
DbCommand command; DbCommand command;
command = (DbCommand)((ICloneable)this._WrappedCommand).Clone(); command = (DbCommand) ((ICloneable) this._WrappedCommand).Clone();
command.CommandText = newCommandText; command.CommandText = newCommandText;
_rowCount = command.ExecuteNonQuery(); _rowCount = command.ExecuteNonQuery();
return _rowCount.Value; return _rowCount.Value;
} }
private bool CheckExists(string commandText, out string newCommandText) private bool CheckExists(string commandText, out string newCommandText)
@ -424,12 +401,15 @@ namespace System.Data.Jet
if (!match.Success) if (!match.Success)
return true; return true;
string not = match.Groups["not"].Value; string not = match.Groups["not"]
string sqlCheckCommand = match.Groups["sqlCheckCommand"].Value; .Value;
newCommandText = match.Groups["sqlCommand"].Value; string sqlCheckCommand = match.Groups["sqlCheckCommand"]
.Value;
newCommandText = match.Groups["sqlCommand"]
.Value;
bool hasRows; bool hasRows;
using (JetCommand command = (JetCommand)((ICloneable)this).Clone()) using (JetCommand command = (JetCommand) ((ICloneable) this).Clone())
{ {
command.CommandText = sqlCheckCommand; command.CommandText = sqlCheckCommand;
using (var reader = command.ExecuteReader()) using (var reader = command.ExecuteReader())
@ -461,13 +441,13 @@ namespace System.Data.Jet
} }
} }
private void SortParameters(string query, DbParameterCollection parameters) private void SortParameters(string query, DbParameterCollection parameters)
{ {
if (parameters.Count == 0) if (parameters.Count == 0)
return; return;
var parameterArray = parameters.Cast<OleDbParameter>().ToArray(); var parameterArray = parameters.Cast<OleDbParameter>()
.ToArray();
// ReSharper disable once CoVariantArrayConversion // ReSharper disable once CoVariantArrayConversion
Array.Sort(parameterArray, new ParameterPositionComparer(query)); Array.Sort(parameterArray, new ParameterPositionComparer(query));
@ -476,7 +456,6 @@ namespace System.Data.Jet
parameters.Add(new OleDbParameter(parameter.ParameterName, parameter.Value)); parameters.Add(new OleDbParameter(parameter.ParameterName, parameter.Value));
} }
private class ParameterPositionComparer : IComparer<DbParameter> private class ParameterPositionComparer : IComparer<DbParameter>
{ {
private readonly string _query; private readonly string _query;
@ -488,62 +467,72 @@ namespace System.Data.Jet
public int Compare(DbParameter x, DbParameter y) public int Compare(DbParameter x, DbParameter y)
{ {
if (x == null) throw new ArgumentNullException(nameof(x)); if (x == null)
if (y == null) throw new ArgumentNullException(nameof(y)); throw new ArgumentNullException(nameof(x));
if (y == null)
throw new ArgumentNullException(nameof(y));
int xPosition = _query.IndexOf(x.ParameterName, StringComparison.Ordinal); int xPosition = _query.IndexOf(x.ParameterName, StringComparison.Ordinal);
int yPosition = _query.IndexOf(y.ParameterName, StringComparison.Ordinal); int yPosition = _query.IndexOf(y.ParameterName, StringComparison.Ordinal);
if (xPosition == -1) xPosition = int.MaxValue; if (xPosition == -1)
if (yPosition == -1) yPosition = int.MaxValue; xPosition = int.MaxValue;
if (yPosition == -1)
yPosition = int.MaxValue;
return xPosition.CompareTo(yPosition); return xPosition.CompareTo(yPosition);
} }
} }
private string[] SplitCommands(string command) private string[] SplitCommands(string command)
{ {
string[] commandParts = string[] commandParts =
command.Replace("\r\n", "\n").Replace("\r", "\n") command.Replace("\r\n", "\n")
.Split(new[] { ";\n" }, StringSplitOptions.None); .Replace("\r", "\n")
.Split(new[] {";\n"}, StringSplitOptions.None);
List<string> commands = new List<string>(commandParts.Length); List<string> commands = new List<string>(commandParts.Length);
foreach (string commandPart in commandParts) foreach (string commandPart in commandParts)
{ {
if (!string.IsNullOrWhiteSpace(commandPart.Replace("\n", "").Replace(";", ""))) if (!string.IsNullOrWhiteSpace(
commandPart.Replace("\n", "")
.Replace(";", "")))
commands.Add(commandPart); commands.Add(commandPart);
} }
return commands.ToArray(); return commands.ToArray();
} }
private string ParseIdentity(string commandText) private string ParseIdentity(string commandText)
{ {
if (commandText.ToLower().Contains("@@identity")) if (commandText.ToLower()
.Contains("@@identity"))
{ {
DbCommand command; DbCommand command;
command = (DbCommand)((ICloneable)this._WrappedCommand).Clone(); command = (DbCommand) ((ICloneable) this._WrappedCommand).Clone();
command.CommandText = "Select @@identity"; command.CommandText = "Select @@identity";
object identity = command.ExecuteScalar(); object identity = command.ExecuteScalar();
int iIdentity = Convert.ToInt32(identity); int iIdentity = Convert.ToInt32(identity);
LogHelper.ShowInfo("@@identity = {0}", iIdentity); LogHelper.ShowInfo("@@identity = {0}", iIdentity);
return Regex.Replace(commandText, "@@identity", iIdentity.ToString(System.Globalization.CultureInfo.InvariantCulture), RegexOptions.IgnoreCase); return Regex.Replace(commandText, "@@identity", iIdentity.ToString(System.Globalization.CultureInfo.InvariantCulture), RegexOptions.IgnoreCase);
} }
return commandText; return commandText;
} }
private string ParseGuid(string commandText) private string ParseGuid(string commandText)
{ {
while (commandText.ToLower().Contains("newguid()")) while (commandText.ToLower()
.Contains("newguid()"))
{ {
_lastGuid = Guid.NewGuid(); _lastGuid = Guid.NewGuid();
commandText = Regex.Replace(commandText, @"newguid\(\)", string.Format("{{{0}}}", _lastGuid), RegexOptions.IgnoreCase); commandText = Regex.Replace(commandText, @"newguid\(\)", string.Format("{{{0}}}", _lastGuid), RegexOptions.IgnoreCase);
} }
if (commandText.ToLower().Contains("@@guid")) if (commandText.ToLower()
.Contains("@@guid"))
{ {
LogHelper.ShowInfo("@@guid = {{{0}}}", _lastGuid); LogHelper.ShowInfo("@@guid = {{{0}}}", _lastGuid);
commandText = Regex.Replace(commandText, "@@guid", string.Format("{{{0}}}", _lastGuid), RegexOptions.IgnoreCase); commandText = Regex.Replace(commandText, "@@guid", string.Format("{{{0}}}", _lastGuid), RegexOptions.IgnoreCase);
} }
return commandText; return commandText;
} }
@ -560,31 +549,38 @@ namespace System.Data.Jet
while (indexOfTop != -1) while (indexOfTop != -1)
{ {
int indexOfTopEnd = newCommandText.IndexOf(" ", indexOfTop + 5, StringComparison.InvariantCultureIgnoreCase); int indexOfTopEnd = newCommandText.IndexOf(" ", indexOfTop + 5, StringComparison.InvariantCultureIgnoreCase);
string stringTopCount = newCommandText.Substring(indexOfTop + 5, indexOfTopEnd - indexOfTop - 5).Trim(); string stringTopCount = newCommandText.Substring(indexOfTop + 5, indexOfTopEnd - indexOfTop - 5)
.Trim();
string[] stringTopCountElements = stringTopCount.Split('+'); string[] stringTopCountElements = stringTopCount.Split('+');
int topCount0; int topCount0;
int topCount1; int topCount1;
if (stringTopCountElements[0].StartsWith("@")) if (stringTopCountElements[0]
topCount0 = Convert.ToInt32(_WrappedCommand.Parameters[stringTopCountElements[0]].Value); .StartsWith("@"))
topCount0 = Convert.ToInt32(
_WrappedCommand.Parameters[stringTopCountElements[0]]
.Value);
else if (!int.TryParse(stringTopCountElements[0], out topCount0)) else if (!int.TryParse(stringTopCountElements[0], out topCount0))
throw new Exception("Invalid TOP clause parameter"); throw new Exception("Invalid TOP clause parameter");
if (stringTopCountElements.Length == 1) if (stringTopCountElements.Length == 1)
topCount1 = 0; topCount1 = 0;
else if (stringTopCountElements[1].StartsWith("@")) else if (stringTopCountElements[1]
topCount1 = Convert.ToInt32(_WrappedCommand.Parameters[stringTopCountElements[1]].Value); .StartsWith("@"))
topCount1 = Convert.ToInt32(
_WrappedCommand.Parameters[stringTopCountElements[1]]
.Value);
else if (!int.TryParse(stringTopCountElements[1], out topCount1)) else if (!int.TryParse(stringTopCountElements[1], out topCount1))
throw new Exception("Invalid TOP clause parameter"); throw new Exception("Invalid TOP clause parameter");
int localTopCount = topCount0 + topCount1; int localTopCount = topCount0 + topCount1;
newCommandText = newCommandText.Remove(indexOfTop + 5, stringTopCount.Length).Insert(indexOfTop + 5, localTopCount.ToString()); newCommandText = newCommandText.Remove(indexOfTop + 5, stringTopCount.Length)
.Insert(indexOfTop + 5, localTopCount.ToString());
if (indexOfTop <= 12) if (indexOfTop <= 12)
topCount = localTopCount; topCount = localTopCount;
indexOfTop = newCommandText.IndexOf(" top ", indexOfTop + 5, StringComparison.InvariantCultureIgnoreCase); indexOfTop = newCommandText.IndexOf(" top ", indexOfTop + 5, StringComparison.InvariantCultureIgnoreCase);
} }
#endregion #endregion
#region SKIP clause #region SKIP clause
@ -593,10 +589,13 @@ namespace System.Data.Jet
if (matchSkipRegularExpression.Success) if (matchSkipRegularExpression.Success)
{ {
string stringSkipCount; string stringSkipCount;
stringSkipCount = matchSkipRegularExpression.Groups["stringSkipCount"].Value; stringSkipCount = matchSkipRegularExpression.Groups["stringSkipCount"]
.Value;
if (stringSkipCount.StartsWith("@")) if (stringSkipCount.StartsWith("@"))
skipCount = Convert.ToInt32(_WrappedCommand.Parameters[stringSkipCount].Value); skipCount = Convert.ToInt32(
_WrappedCommand.Parameters[stringSkipCount]
.Value);
else if (!int.TryParse(stringSkipCount, out skipCount)) else if (!int.TryParse(stringSkipCount, out skipCount))
throw new Exception("Invalid SKIP clause parameter"); throw new Exception("Invalid SKIP clause parameter");
newCommandText = newCommandText.Remove(matchSkipRegularExpression.Index, matchSkipRegularExpression.Length); newCommandText = newCommandText.Remove(matchSkipRegularExpression.Index, matchSkipRegularExpression.Length);
@ -632,22 +631,15 @@ namespace System.Data.Jet
/// </value> /// </value>
public override UpdateRowSource UpdatedRowSource public override UpdateRowSource UpdatedRowSource
{ {
get get { return this._WrappedCommand.UpdatedRowSource; }
{ set { this._WrappedCommand.UpdatedRowSource = value; }
return this._WrappedCommand.UpdatedRowSource;
}
set
{
this._WrappedCommand.UpdatedRowSource = value;
}
} }
public static implicit operator OleDbCommand(JetCommand command) public static implicit operator OleDbCommand(JetCommand command)
{ {
return (OleDbCommand)command._WrappedCommand; return (OleDbCommand) command._WrappedCommand;
} }
/// <summary> /// <summary>
/// Clones this instance. /// Clones this instance.
/// </summary> /// </summary>
@ -657,11 +649,9 @@ namespace System.Data.Jet
JetCommand clone = new JetCommand(); JetCommand clone = new JetCommand();
clone._Connection = this._Connection; clone._Connection = this._Connection;
clone._WrappedCommand = (DbCommand)((ICloneable)this._WrappedCommand).Clone(); clone._WrappedCommand = (DbCommand) ((ICloneable) this._WrappedCommand).Clone();
return clone; return clone;
} }
} }
}
}

@ -1,36 +0,0 @@
using System.Data.Common;
namespace System.Data.Jet
{
internal class JetDummyTransaction : JetTransaction
{
private readonly JetConnection _connection;
internal override DbTransaction WrappedTransaction => null;
public JetDummyTransaction(JetConnection connection, IsolationLevel isolationLevel)
{
_connection = connection;
IsolationLevel = isolationLevel;
LogHelper.ShowCommandHeader($"\r\nvvv BeginTransaction ({isolationLevel}): DUMMY!");
}
public override void Commit()
{
LogHelper.ShowCommandHeader("--- Commit: DUMMY!");
_connection.ActiveTransaction = null;
}
protected override DbConnection DbConnection
=> _connection;
public override IsolationLevel IsolationLevel { get; }
public override void Rollback()
{
LogHelper.ShowCommandHeader("^^^ Rollback: DUMMY!");
_connection.ActiveTransaction = null;
}
}
}
Loading…
Cancel
Save