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; } } }