namespace Ion.Storage { using Holo; using MySql.Data.MySqlClient; using System; using System.Data; using System.Threading; public class DatabaseManager { private bool[] mClientAvailable; private Thread mClientMonitor; private DatabaseClient[] mClients; private int mClientStarvationCounter; private Database mDatabase; private DatabaseServer mServer; public DatabaseManager(DatabaseServer pServer, Database pDatabase) { this.mClients = new DatabaseClient[0]; this.mClientAvailable = new bool[0]; this.mServer = pServer; this.mDatabase = pDatabase; } public DatabaseManager(string sServer, uint Port, string sUser, string sPassword, string sDatabase, uint minPoolSize, uint maxPoolSize) { this.mClients = new DatabaseClient[0]; this.mClientAvailable = new bool[0]; this.mServer = new DatabaseServer(sServer, Port, sUser, sPassword); this.mDatabase = new Database(sDatabase, minPoolSize, maxPoolSize); this.mClientMonitor = new Thread(new ThreadStart(this.MonitorClientsLoop)); this.mClientMonitor.Priority = ThreadPriority.Lowest; this.mClientMonitor.Start(); } public string CreateConnectionString() { return new MySqlConnectionStringBuilder { Server = this.mServer.Host, Port = this.mServer.Port, UserID = this.mServer.User, Password = this.mServer.Password, Database = this.mDatabase.Name, MinimumPoolSize = this.mDatabase.minPoolSize, MaximumPoolSize = this.mDatabase.maxPoolSize }.ToString(); } public void DELETE(IDataObject obj) { using (DatabaseClient client = this.GetClient()) { obj.DELETE(client); } } public void DestroyClients() { lock (this) { for (int i = 0; i < this.mClients.Length; i++) { this.mClients[i].Destroy(); this.mClients[i] = null; } } } public void DestroyManager() { this.mServer = null; this.mDatabase = null; this.mClients = null; this.mClientAvailable = null; this.mClientMonitor = null; } public DatabaseClient GetClient() { lock (this) { for (uint i = 0; i < this.mClients.Length; i++) { if (this.mClientAvailable[i]) { this.mClientStarvationCounter = 0; if (this.mClients[i].State == ConnectionState.Broken) { this.mClients[i] = new DatabaseClient(i + 1, this); } if (this.mClients[i].State == ConnectionState.Closed) { this.mClients[i].Connect(); } if (this.mClients[i].State == ConnectionState.Open) { this.mClientAvailable[i] = false; this.mClients[i].UpdateLastActivity(); return this.mClients[i]; } } } this.mClientStarvationCounter++; if (this.mClientStarvationCounter >= ((this.mClients.Length + 1) / 2)) { this.mClientStarvationCounter = 0; this.SetClientAmount((uint) (this.mClients.Length + 1.3f)); return this.GetClient(); } DatabaseClient client = new DatabaseClient(0, this); client.Connect(); return client; } } public int GetOpenConnectionCount() { int num = 0; for (int i = 0; i < this.mClients.Length; i++) { if (this.mClients[i].State == ConnectionState.Open) { num++; } } return num; } public int getStarvationNumber() { return this.mClientStarvationCounter; } public void INSERT(IDataObject obj) { using (DatabaseClient client = this.GetClient()) { obj.INSERT(client); } } private void MonitorClientsLoop() { Label_0000: try { lock (this) { DateTime now = DateTime.Now; for (int i = 0; i < this.mClients.Length; i++) { if ((this.mClients[i].State != ConnectionState.Closed) && (this.mClients[i].Inactivity >= 0x2d)) { this.mClients[i].Disconnect(); } } } Thread.Sleep(0x2710); goto Label_0000; } catch (ThreadAbortException) { goto Label_0000; } catch (Exception exception) { Out.WriteError(exception.Message); goto Label_0000; } } public void ReleaseClient(uint Handle) { if (this.mClients.Length >= (Handle - 1)) { this.mClientAvailable[(int) ((IntPtr) (Handle - 1))] = true; } } public void SetClientAmount(uint Amount) { lock (this) { if (this.mClients.Length != Amount) { if (Amount < this.mClients.Length) { for (uint j = Amount; j < this.mClients.Length; j++) { this.mClients[j].Destroy(); this.mClients[j] = null; } } DatabaseClient[] clientArray = new DatabaseClient[Amount]; bool[] flagArray = new bool[Amount]; for (uint i = 0; i < Amount; i++) { if (i < this.mClients.Length) { clientArray[i] = this.mClients[i]; flagArray[i] = this.mClientAvailable[i]; } else { clientArray[i] = new DatabaseClient(i + 1, this); flagArray[i] = true; } } this.mClients = clientArray; this.mClientAvailable = flagArray; } } } public void StartMonitor() { this.mClientMonitor = new Thread(new ThreadStart(this.MonitorClientsLoop)); this.mClientMonitor.Priority = ThreadPriority.Lowest; this.mClientMonitor.Start(); } public void StopMonitor() { if (this.mClientMonitor != null) { this.mClientMonitor.Abort(); } } public override string ToString() { return (this.mServer.ToString() + ":" + this.mDatabase.Name); } public void UPDATE(IDataObject obj) { using (DatabaseClient client = this.GetClient()) { obj.UPDATE(client); } } public int databaseClients { get { return this.GetOpenConnectionCount(); } } } }