kreta/Sda.DataProvider/SDACommand.cs
2024-03-13 00:33:46 +01:00

273 lines
8.2 KiB
C#

using System;
using System.Data;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using JetBrains.Annotations;
using SDA.DataProvider.Core;
namespace SDA.DataProvider
{
/// <summary>
/// Adatbázis-parancs.
/// </summary>
public class SDACommand : IDisposable
{
[NotNull]
internal SDACommandWrapper Command;
[CanBeNull]
internal SDAConnection InnerConnection;
[NotNull]
internal SDACommandParameterCollection InnerParameters;
/// <summary>
/// Létrehoz egy új adatbázis-parancs objektum példányt.
/// </summary>
public SDACommand()
{
if (SDAFactory.Instance == null)
{
throw new InvalidOperationException("SDAFactory.Instance");
}
Command = SDAFactory.Instance.CreateCommand();
InnerParameters = new SDACommandParameterCollection(Command);
// Csak hogy mindig legyen explicit beállítva...
Command.CommandType = CommandType.Text;
// Ha van beállított Command Timeout, akkor átadjuk
if (SDAFactory.Instance.CommandTimeout.HasValue)
{
Command.CommandTimeout = SDAFactory.Instance.CommandTimeout.Value;
}
}
/// <summary>
/// Létrehoz egy új adatbázis-parancs objektum példányt.
/// </summary>
/// <param name="commandText">SQL parancs</param>
/// <param name="connection">Adatbázis kacsolat</param>
public SDACommand(string commandText, SDAConnection connection)
{
if (connection == null)
{
throw new ArgumentNullException(nameof(connection));
}
if (SDAFactory.Instance == null)
{
throw new InvalidOperationException("SDAFactory.Instance");
}
Command = SDAFactory.Instance.CreateCommand();
InnerParameters = new SDACommandParameterCollection(Command);
InnerConnection = connection;
CommandText = commandText;
Command.Connection = connection.Connection;
// Ha van beállított Command Timeout, akkor átadjuk
if (SDAFactory.Instance.CommandTimeout.HasValue)
{
Command.CommandTimeout = SDAFactory.Instance.CommandTimeout.Value;
}
}
internal SDACommand(SDACommandWrapper command)
{
Command = command;
InnerParameters = new SDACommandParameterCollection(Command);
// Ha van beállított Command Timeout, akkor átadjuk
if (SDAFactory.Instance.CommandTimeout.HasValue)
{
Command.CommandTimeout = SDAFactory.Instance.CommandTimeout.Value;
}
}
bool _disposed;
/// <summary>
/// Explicit destruktor.
/// </summary>
/// <param name="disposing">Programozott felszabadítás?</param>
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
Command.Dispose();
}
_disposed = true;
}
/// <summary>
/// Eldobja az objektumot.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// A parancs SQL szövege.
/// </summary>
[SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")]
[CanBeNull]
public virtual string CommandText
{
get
{
return Command.CommandText;
}
set
{
Command.CommandText = value;
}
}
/// <summary>
/// A parancs maximális futási ideje másodpercben.
/// </summary>
public int CommandTimeout
{
get
{
return Command.CommandTimeout;
}
set
{
Command.CommandTimeout = value;
}
}
/// <summary>
/// A parancs adatbázis-kapcsolata.
/// </summary>
[CanBeNull]
public virtual SDAConnection Connection
{
get
{
return InnerConnection;
}
set
{
InnerConnection = value;
Command.Connection = value?.Connection;
}
}
/// <summary>
/// Végrehajtja a parancsot, és visszatér az eredmény első sorának első oszlopának értékével.
/// </summary>
/// <returns>Az eredmény első sorának első oszlopának értéke</returns>
[CanBeNull]
public virtual object ExecuteScalar()
{
return !SDAConnectionDiagnostics.DiagnosticEnable
? Command.ExecuteScalar()
: ExecuteWithDiagnostic(Command.ExecuteScalar, ExecutionType.Scalar);
}
/// <summary>
/// Végrehajtja a parancsot és egy SDADataReader objektumot épít a válasz feldolgozására.
/// </summary>
/// <returns>Egy SDADataReader objektum</returns>
[NotNull]
public SDADataReader ExecuteReader()
{
return !SDAConnectionDiagnostics.DiagnosticEnable
? new SDADataReader(Command.ExecuteReader())
: new SDADataReader(ExecuteWithDiagnostic(Command.ExecuteReader, ExecutionType.Scalar));
}
/// <summary>
/// Végrehajtja a parancsot és egy SDADataReader objektumot épít a válasz feldolgozására.
/// </summary>
/// <param name="commandBehavior">A parancs végrehajtásának tulajdonságai</param>
/// <returns>Egy SDADataReader objektum</returns>
[NotNull]
public SDADataReader ExecuteReader(CommandBehavior commandBehavior)
{
return !SDAConnectionDiagnostics.DiagnosticEnable
? new SDADataReader(Command.ExecuteReader(commandBehavior))
: new SDADataReader(ExecuteWithDiagnostic(() => Command.ExecuteReader(commandBehavior), ExecutionType.Scalar));
}
/// <summary>
/// Végrehajtja a parancsot, és visszatér a művelet által érintett sorok számával.
/// </summary>
/// <returns>A művelet által érintett sorok száma</returns>
public int ExecuteNonQuery()
{
return Command.ExecuteNonQuery();
}
/// <summary>
/// A parancsból egy előkészített változatot hoz létre az adatbázis-kiszolgálón.
/// </summary>
public void Prepare()
{
Command.Prepare();
}
/// <summary>
/// Leállítja a parancs végrehajtását.
/// </summary>
public void Cancel()
{
Command.Cancel();
}
/// <summary>
/// A parancs paramétereinek listája.
/// </summary>
[NotNull]
public virtual SDACommandParameterCollection Parameters => InnerParameters;
/// <summary>
/// A parancshoz tartozó adatbázis-ügylet.
/// </summary>
[CanBeNull]
public virtual SDATransaction Transaction
{
get
{
return null;
}
set
{
Command.Transaction = value?.Transaction;
}
}
/// <summary>
/// A parancs típusa.
/// </summary>
public CommandType CommandType
{
get
{
return Command.CommandType;
}
set
{
Command.CommandType = value;
}
}
private TResult ExecuteWithDiagnostic<TResult>(Func<TResult> f, ExecutionType executionType)
{
var watch = new Stopwatch();
watch.Start();
var result = f();
watch.Stop();
SDAConnectionDiagnostics.RaiseCommandExecutedEvent(this, new CommandExecutedEventArgs(watch.Elapsed, executionType));
return result;
}
}
}