//==============================================================
//  版权所有：深圳杰文科技
//  文件名：OracleDao.cs
//  版本：V1.0  
//  创建者：Jay  ( QQ： 85363208 )
//  创建时间：2017-11-28 16:18
//  创建描述：
//  修改者：
//  修改时间：
//  修改说明： 
//==============================================================

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using Infrastructure.Utilities;
using Oracle.ManagedDataAccess.Client;

namespace Infrastructure.DAO
{
	//Oracle数据管道，专门用于读取Oracle数据。对数据只读取不加工。
	public class OracleDao : IDbDao
	{
		private const DataSourceSetting.DbTypes dbType = DataSourceSetting.DbTypes.Oracle;

		public List<T> Select<T>(string connectionString, string where) where T : new()
		{
			string tableName = DbUtil.GetTableName(typeof(T));
			string sql = "select * from {0} where 1=1 {1}".Fmt(tableName, where);
			DbUtil.Log(sql);

			List<T> list = null;
			using (OracleConnection conn = new OracleConnection(connectionString))
			{
				conn.Open();

				using (OracleDataAdapter da = new OracleDataAdapter(sql, conn))
				{
					using (DataTable table = new DataTable())
					{
						da.Fill(table);
						list = table.ToList<T>();
						table.Dispose();
					}

					da.Dispose();
				}

				conn.Close();
				conn.Dispose();
			}

			return list;
		}

		public T FirstOrDefault<T>(string connectionString, string where) where T : new()
		{
			Type type = typeof(T);

			string tableName = DbUtil.GetTableName(type);
			string sql = "select * from {0} where rownum <= 1 {1}".Fmt(tableName, where);
			DbUtil.Log(sql);

			using (OracleConnection conn = new OracleConnection(connectionString))
			{
				conn.Open();

				using (OracleDataAdapter da = new OracleDataAdapter(sql, conn))
				{
					using (DataTable table = new DataTable())
					{
						da.Fill(table);
						if (table.Rows.Count == 0)
						{
							return default(T);
						}
						else
						{
							T obj = table.Rows[0].To<T>();
							return obj;
						}
					}
				}
			}
		}

		public int Insert<T>(string connectionString, T entity)
		{
			string sql = DbUtil.GenerateInsertSql(dbType, typeof(T), entity);
			int cnt = Execut(connectionString, sql);
			return cnt;
		}

		public int Update<T>(string connectionString, T entity)
		{
			string sql = DbUtil.GenerateUpdateSql(dbType, typeof(T), entity);
			int cnt = Execut(connectionString, sql);
			return cnt;
		}

		public int Delete<T>(string connectionString, object id)
		{
			string sql = DbUtil.GenerateDeleteSql(dbType, typeof(T), id);
			int cnt = Execut(connectionString, sql);
			return cnt;
		}

		private int Execut(string connectionString, string sql)
		{
			DbUtil.Log(sql);
			using (OracleConnection conn = new OracleConnection(string.Format(connectionString)))
			{
				conn.Open();

				OracleCommand cmd = conn.CreateCommand();
				cmd.CommandType = CommandType.Text;
				cmd.CommandText = sql;
				int cnt = cmd.ExecuteNonQuery();

				conn.Close();
				conn.Dispose();

				return cnt;
			}
		}

		public void Proc(string connectionString, string procName, IEnumerable<DbParameter> parameters)
		{
			DbUtil.Log("exec procName ...");
			throw new NotImplementedException();
		}

		public bool Open(string connectionString, out string exception)
		{
			exception = "";
			using (OracleConnection conn = new OracleConnection(connectionString))
			{
				try
				{
					conn.Open();
				}
				catch (Exception ex)
				{
					exception = ex.InnerException == null ? ex.Message : ex.InnerException.Message;
					return false;
				}
			}
			return true;
		}

		public string GetTimestampWhere(Type type, DateTime startTimestamp, DateTime endTimestamp)
		{
			if (startTimestamp == endTimestamp)
			{
				throw new Exception("时间戳的开始和结束时间不能相等");
			}

			string timestampWhere = "";
			string timestampFieldName = DbUtil.GetTimestampFieldName(type);
			if (!timestampFieldName.IsNullOrEmpty())
			{
				timestampWhere = "({0} >= to_timestamp('{1}', 'yyyy-MM-dd HH24:MI:ss.ff') and {0} <= to_timestamp('{2}', 'yyyy-MM-dd HH24:MI:ss.ff') )".Fmt(timestampFieldName, startTimestamp, endTimestamp);
			}
			return timestampWhere;
		}

		public bool BeginTransaction(string connectionString)
		{
			throw new NotImplementedException();
		}

		public bool CommitTransaction(string connectionString)
		{
			throw new NotImplementedException();
		}

		public void Dispose()
		{
			throw new NotImplementedException();
		}
	}
}
