using System;
using System.Data;
using System.Data.SqlClient;
using DFEngine.Logging;
using DFEngine.Server;
namespace DFEngine.Database
{
///
/// Represents a client of a database,
///
public sealed class DatabaseClient : IDisposable
{
#region Fields
private double _lastActivity;
public SqlConnection Connection { get; private set; }
public SqlCommand Command;
private DatabaseManager _manager;
#endregion Fields
#region Properties
public int Id { get; }
public bool Available { get; set; }
public double TimeInactive => UnixTimestamp.GetCurrent() - _lastActivity;
#endregion Properties
#region Constructor
///
/// Constructs a new database client with a given handle to a given database proxy.
///
/// The identifier of this database client as an unsigned 32 bit integer.
/// The to use
/// The instance of the DatabaseManager that manages the database proxy of this database client.
internal DatabaseClient(int id, SqlConnection conn, DatabaseManager manager)
{
this.Id = id;
Connection = conn;
Command = Connection.CreateCommand();
_manager = manager;
Available = true;
UpdateLastActivity();
}
#endregion Constructor
///
/// Called when released from using() scope - does not actually dispose, just marks as available
///
public void Dispose()
{
ResetCommand();
Available = true;
UpdateLastActivity();
if (ServerMainDebug.DebugSql) DatabaseLog.Write(DatabaseLogLevel.Debug, "(Sql)Released client " + Id + " for availability.");
}
public void Close()
{
Connection.Close();
Command.Dispose();
Connection = null;
Command = null;
}
private void UpdateLastActivity()
{
_lastActivity = UnixTimestamp.GetCurrent();
}
public void ResetCommand()
{
Command.CommandText = null;
ClearParameters();
}
public void ClearParameters()
{
Command.Parameters.Clear();
}
public void SetParameter(string Key, object Value)
{
Command.Parameters.Add(new SqlParameter(Key, Value));
}
public SqlParameter SetParameter(string Key, SqlDbType pType, ParameterDirection direction)
{
var idParam = Command.Parameters.Add(new SqlParameter(Key, pType)
{
Direction = direction,
});
return idParam;
}
public void CreateStoredProcedure(string CommandText)
{
SqlCommand cmd = Connection.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = CommandText;
Command = cmd;
}
public int ExecuteNonQuery()
{
Command.Connection = Connection;
int Effects = Command.ExecuteNonQuery();
ResetCommand();
return Effects;
}
public object ExecuteScalar()
{
Command.Connection = Connection;
object result = Command.ExecuteScalar();
ResetCommand();
return result;
}
public SqlDataReader ExecuteReader(SqlCommand cmd)
{
cmd.Connection = Connection;
return cmd.ExecuteReader();
}
public bool CheckConnection()
{
return Connection.State == ConnectionState.Open;
}
}
}