using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Data.AccessClient;
using Medivators.BusinessObjects;
using Medivators.Common;
using Medivators.Common.Enums;
using Medivators.Common.Logging;


namespace Medivators.Data.Queries
{
	public class SynchronousExecute : IDisposable
	{
		private long _id = Sequence.GetInstance().NextValue;

		public virtual void Dispose() {}
		public long DataOperationID
		{
			get { return _id; }
		}

		protected int Insert(string SQL)
		{
			Log.GetInstance().WriteLog(LogEntryType.DebugTrace,
										"Executing Insert DataOperationID = " +
										DataOperationID.ToString() +
										" SQL: " + SQL);
			return ExecuteNonQuery(SQL);
		}
		protected int Update(string SQL)
		{
			Log.GetInstance().WriteLog(LogEntryType.DebugTrace,
										"Executing Update DataOperationID = " +
										DataOperationID.ToString() +
										" SQL: " + SQL);
			return ExecuteNonQuery (SQL);
		}
		protected int Delete(string SQL)
		{
			Log.GetInstance().WriteLog(LogEntryType.DebugTrace,
										"Executing Delete DataOperationID = " +
										DataOperationID.ToString() +
										" SQL: " + SQL);
			return ExecuteNonQuery(SQL);
		}

		protected object SelectScalar(string SQL)
		{
			Log.GetInstance().WriteLog(LogEntryType.DebugTrace,
										"Executing SelectScalar DataOperationID = " +
										DataOperationID.ToString() +
										" SQL: " + SQL);
			return ExecuteScalar(SQL);
		}

		protected virtual ArrayList Select(string SQL, UntypedDataMapper Mapper)
		{
			Log.GetInstance().WriteLog(LogEntryType.DebugTrace,
										"Executing Select DataOperationID = " +
										DataOperationID.ToString() +
										" SQL: " + SQL);
			return ExecuteReader(SQL, Mapper);
		}
		protected virtual List<IBusinessObject> Select(string SQL, IDataMapper Mapper)
		{
			Log.GetInstance().WriteLog(LogEntryType.DebugTrace,
										"Executing Select DataOperationID = " +
										DataOperationID.ToString() +
										" SQL: " + SQL);
			return ExecuteReader(SQL, (IBusinessObjectDataMapper)Mapper);
		}

		private int ExecuteNonQuery(object SQL)
		{
			try
			{
				using (AccessCommand cmd = new AccessCommand())
				{
					Connection.GetInstance().Open();
					cmd.Connection = Connection.GetInstance();
					cmd.CommandText = (string)SQL;
					return cmd.ExecuteNonQuery();
				}
			}
			catch 
			{
				throw;
			}
		}
		private ArrayList ExecuteReader(string SQL, UntypedDataMapper Mapper)
		{
			try
			{
				using (AccessCommand cmd = new AccessCommand())
				{
					Connection.GetInstance().Open();
					cmd.Connection = Connection.GetInstance();
					cmd.CommandText = SQL;
					using (OleDbDataReader rdr = (OleDbDataReader)cmd.ExecuteReader())
					{
						Mapper.Reader = rdr;
						rdr.Close();
					}
				}
				return Mapper.Data;
			}
			catch
			{
				throw;
			}
		}
		private List<IBusinessObject> ExecuteReader(string SQL, IBusinessObjectDataMapper Mapper)
		{
			try
			{
				using (AccessCommand cmd = new AccessCommand())
				{
					Connection.GetInstance().Open();
					cmd.Connection = Connection.GetInstance();
					cmd.CommandText = SQL;
					using (OleDbDataReader rdr = (OleDbDataReader)cmd.ExecuteReader())
					{
						Mapper.Reader = rdr;
						rdr.Close();
					}
				}
				return Mapper.BusinessObjectCollection;
			}
			catch 
			{
				throw;
			}
		}
		private object ExecuteScalar(string SQL)
		{
			try
			{
				using (AccessCommand cmd = new AccessCommand())
				{
					Connection.GetInstance().Open();
					cmd.Connection = Connection.GetInstance();
					cmd.CommandText = (string)SQL;
					return cmd.ExecuteScalar();
				}
			}
			catch
			{
				throw;
			}
		}
	}
}
