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