ModernUO/Scripts/Engines/MyRunUO/DatabaseCommandQueue.cs
Mark Sturgill d2c670f5c3 Implement Core.TickCount
Convert movement, actions (lift/use), combat, and spells to use Core.TickCount and avoid DateTime caveats (performance, system time dependency, etc)
Refactor DateTime.Now to DateTime.UtcNow
Add LOS check for Iron Maiden addon
2013-10-06 03:21:18 -07:00

202 lines
No EOL
4.8 KiB
C#

using System;
using System.Threading;
using System.Collections;
using System.Data;
using System.Data.Odbc;
namespace Server.Engines.MyRunUO
{
public class DatabaseCommandQueue
{
private Queue m_Queue;
private ManualResetEvent m_Sync;
private Thread m_Thread;
private bool m_HasCompleted;
private string m_CompletionString;
private string m_ConnectionString;
public bool HasCompleted
{
get{ return m_HasCompleted; }
}
public void Enqueue( object obj )
{
lock ( m_Queue.SyncRoot )
{
m_Queue.Enqueue( obj );
try{ m_Sync.Set(); }
catch{}
}
}
public DatabaseCommandQueue( string completionString, string threadName ) : this( Config.CompileConnectionString(), completionString, threadName )
{
}
public DatabaseCommandQueue( string connectionString, string completionString, string threadName )
{
m_CompletionString = completionString;
m_ConnectionString = connectionString;
m_Queue = Queue.Synchronized( new Queue() );
m_Queue.Enqueue( null ); // signal connect
/*m_Queue.Enqueue( "DELETE FROM myrunuo_characters" );
m_Queue.Enqueue( "DELETE FROM myrunuo_characters_layers" );
m_Queue.Enqueue( "DELETE FROM myrunuo_characters_skills" );
m_Queue.Enqueue( "DELETE FROM myrunuo_guilds" );
m_Queue.Enqueue( "DELETE FROM myrunuo_guilds_wars" );*/
m_Sync = new ManualResetEvent( true );
m_Thread = new Thread( new ThreadStart( Thread_Start ) );
m_Thread.Name = threadName;//"MyRunUO Database Command Queue";
m_Thread.Priority = Config.DatabaseThreadPriority;
m_Thread.Start();
}
private void Thread_Start()
{
bool connected = false;
OdbcConnection connection = null;
OdbcCommand command = null;
OdbcTransaction transact = null;
DateTime start = DateTime.UtcNow;
bool shouldWriteException = true;
while ( true )
{
m_Sync.WaitOne();
while ( m_Queue.Count > 0 )
{
try
{
object obj = m_Queue.Dequeue();
if ( obj == null )
{
if ( connected )
{
if ( transact != null )
{
try{ transact.Commit(); }
catch ( Exception commitException )
{
Console.WriteLine( "MyRunUO: Exception caught when committing transaction" );
Console.WriteLine( commitException );
try
{
transact.Rollback();
Console.WriteLine( "MyRunUO: Transaction has been rolled back" );
}
catch ( Exception rollbackException )
{
Console.WriteLine( "MyRunUO: Exception caught when rolling back transaction" );
Console.WriteLine( rollbackException );
}
}
}
try{ connection.Close(); }
catch{}
try{ connection.Dispose(); }
catch{}
try{ command.Dispose(); }
catch{}
try{ m_Sync.Close(); }
catch{}
Console.WriteLine( m_CompletionString, (DateTime.UtcNow - start).TotalSeconds );
m_HasCompleted = true;
return;
}
else
{
try
{
connected = true;
connection = new OdbcConnection( m_ConnectionString );
connection.Open();
command = connection.CreateCommand();
if ( Config.UseTransactions )
{
transact = connection.BeginTransaction();
command.Transaction = transact;
}
}
catch ( Exception e )
{
try{ if ( transact != null ) transact.Rollback(); }
catch{}
try{ if ( connection != null ) connection.Close(); }
catch{}
try{ if ( connection != null ) connection.Dispose(); }
catch{}
try{ if ( command != null ) command.Dispose(); }
catch{}
try{ m_Sync.Close(); }
catch{}
Console.WriteLine( "MyRunUO: Unable to connect to the database" );
Console.WriteLine( e );
m_HasCompleted = true;
return;
}
}
}
else if ( obj is string )
{
command.CommandText = (string)obj;
command.ExecuteNonQuery();
}
else
{
string[] parms = (string[])obj;
command.CommandText = parms[0];
if ( command.ExecuteScalar() == null )
{
command.CommandText = parms[1];
command.ExecuteNonQuery();
}
}
}
catch ( Exception e )
{
if ( shouldWriteException )
{
Console.WriteLine( "MyRunUO: Exception caught in database thread" );
Console.WriteLine( e );
shouldWriteException = false;
}
}
}
lock ( m_Queue.SyncRoot )
{
if ( m_Queue.Count == 0 )
m_Sync.Reset();
}
}
}
}
}