using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
using System.Threading;
namespace Blizzard
{
///
/// Manages and maintains connections to a MySql server.
///
sealed class MySQLManager
{
private const bool DEBUG = true;
///
/// Contains a pool of re-usable pre-allocated MySQLConnection instances.
///
private MySQLConnectionPool Pool;
///
/// The amount of connections available, if this becomes 0 then MySQL is starving and an increase of the pool is recommended.
///
private Int32 ConnectionsAvailable;
///
/// The connection string used for connecting to the MySQL server.
///
private string ConnectionString;
///
/// Represents if this manager is ready for use.
///
private bool Active;
private void WriteDebug(string line)
{
if (DEBUG)
{
BlizzardSystem.WriteLine("[MySQL]: " + line);
}
}
public MySQLManager(MySqlConnectionStringBuilder consb)
{
this.ConnectionsAvailable = 0;
this.ConnectionString = consb.ToString();
this.Pool = new MySQLConnectionPool((Int32)consb.MaximumPoolSize);
// Pre-allocate connection instances in the pool
for (Int32 i = 0; i < (Int32)consb.MaximumPoolSize; i++)
{
// Create and push
this.Pool.Push(new MySQLConnection(this, this.ConnectionString));
Interlocked.Increment(ref this.ConnectionsAvailable);
}
this.WriteDebug("Connections available: " + this.ConnectionsAvailable);
}
///
/// Allows for connections to be obtained, sets the manager in a ready state.
///
public void Start()
{
this.Active = true;
WriteDebug("MySQL is now ready for use.");
}
///
/// Finds a connection and returns it.
///
/// MySQLConnection instance from the stack.
public MySQLConnection GetConnection()
{
if (!this.Active)
{
throw new InvalidOperationException("MySQL Manager is not yet active, it may have been shutdown or not started correctly.");
}
MySQLConnection c = this.Pool.Pop();
if (c != null)
{
Interlocked.Decrement(ref this.ConnectionsAvailable);
this.WriteDebug("Connections available: " + this.ConnectionsAvailable);
c.Open();
return c;
}
else
{
Console.WriteLine("No more connections are available right now.");
return null;
}
}
///
/// Releases the connection instance back into the stack.
///
/// The connection to release.
public void ReleaseConnection(MySQLConnection c)
{
this.Pool.Push(c);
Interlocked.Increment(ref this.ConnectionsAvailable);
this.WriteDebug("Connections available: " + this.ConnectionsAvailable);
}
public void Shutdown()
{
// Stop all operation
this.Active = false;
// Clear the MySQL side of the pool
MySqlConnection.ClearAllPools();
// Empty the connection string
this.ConnectionString = string.Empty;
// Clear our side of the pool (the references to our MySQLConnections)
this.Pool.Clear();
}
public string GetConnectionString()
{
return this.ConnectionString;
}
}
}