using System; using System.Data.Common; using System.Threading.Tasks; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Dbas; using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Dbas.Base; namespace Sarand.Net.Standard.Dbas.Data { //======================================================================= public class DbResultSet_DataReader : DbResultSet { //------------------------------------------------------------------- // Data members. private class DataMembers { // Construction. public DataMembers (ISacsDatabase database, String query) { Database = database; Query = query; } // Properties. public ISacsDatabase Database { get; } public String Query { get; } public DbConnection DbConnection { get; set; } public DbCommand DbCommand { get; set; } public DbDataReader DbDataReader { get; set; } // Result set schema - to avoid keeping connection open. public String[] ColumnNames { get; set; } public String[] ColumnTypeNames { get; set; } public void PopulateColumns () { int fieldCount = DbDataReader.FieldCount; ColumnNames = new String[fieldCount]; ColumnTypeNames = new String[fieldCount]; for (int columnIdx = 0; columnIdx < fieldCount; columnIdx++) { ColumnNames[columnIdx] = DbDataReader.GetName(columnIdx); ColumnTypeNames[columnIdx] = DbDataReader.GetDataTypeName(columnIdx); } } } private readonly DataMembers data; //------------------------------------------------------------------- // Construction. [Obsolete("Constructor is deprecated. Use ExecuteQuery[Async] instead.")] public DbResultSet_DataReader (SacsDatabase database, String query) { data = new DataMembers(database, query); String fn = GetType().Name + ".CTR"; try { ExecuteQuery_Internal(data); Log(fn, "Query: " + data.Query + (HasRows ? " [has rows]" : " [no rows]"), SaMessageLevel.Debug); } catch (Exception exc) { SetErrorState(ExceptionUtil.GetErrorStateMessage(exc)); SaLogger.Warn(fn + " " + ExceptionUtil.GetLogMessage(exc, 6) + "\n\t Query: " + query, true); } } /// Private construction - created from ExecuteQuery{Async]. private DbResultSet_DataReader (DataMembers data) { this.data = data; } protected override void Dispose (bool disposing) { if (disposing) Close(); } //------------------------------------------------------------------- // Execute query. public static DbResultSet_DataReader ExecuteQuery (ISacsDatabase database, String query) { DataMembers data = new DataMembers(database, query); String errorState = ""; try { ExecuteQuery_Internal(data); Log(SysUtil.Fn, "Query: " + data.Query + (data.DbDataReader.HasRows ? " [has rows]" : " [no rows]"), SaMessageLevel.Debug); } catch (Exception exc) { errorState = ExceptionUtil.GetErrorStateMessage(exc); SaLogger.Warn(SysUtil.Fn + " " + ExceptionUtil.GetLogMessage(exc, 6) + "\n\t Query: " + query, true); } DbResultSet_DataReader resultSet = new DbResultSet_DataReader (data); resultSet.SetErrorState(errorState); return resultSet; } public static async Task ExecuteQueryAsync (ISacsDatabase database, String query) { DataMembers data = new DataMembers(database, query); String errorState = ""; try { data.DbConnection = data.Database.CreateConnection(); data.DbCommand = data.DbConnection.CreateCommand(); data.DbConnection.Open(); data.DbCommand.CommandText = data.Database.GetSelectQueryPrefix() + data.Query; data.DbDataReader = await data.DbCommand.ExecuteReaderAsync(); data.PopulateColumns(); Log(SysUtil.Fn, "Query: " + data.Query + (data.DbDataReader.HasRows ? " [has rows]" : " [no rows]"), SaMessageLevel.Debug); } catch (Exception exc) { errorState = ExceptionUtil.GetErrorStateMessage(exc); SaLogger.Warn(SysUtil.Fn + " " + ExceptionUtil.GetLogMessage(exc, 6) + "\n\t Query: " + query, true); } DbResultSet_DataReader resultSet = new DbResultSet_DataReader (data); resultSet.SetErrorState(errorState); return resultSet; } //------------------------------------------------------------------- // Close. public override void Close () { // Dispose of database objects. if (data.DbDataReader != null && !data.DbDataReader.IsClosed) data.DbDataReader.Close(); data.DbDataReader = null; if (data.DbCommand != null) data.DbCommand.Dispose(); data.DbCommand = null; if (data.DbConnection != null) data.DbConnection.Dispose(); data.DbConnection = null; } //------------------------------------------------------------------- // Execute query. private static void ExecuteQuery_Internal (DataMembers data) { data.DbConnection = data.Database.CreateConnection(); data.DbCommand = data.DbConnection.CreateCommand(); data.DbConnection.Open(); data.DbCommand.CommandText = data.Database.GetSelectQueryPrefix() + data.Query; data.DbDataReader = data.DbCommand.ExecuteReader(); data.PopulateColumns(); } //------------------------------------------------------------------- // Navigation. public override bool NextRecord () { // Move to next result. bool nextRecord = false; if (data.DbDataReader != null) { nextRecord = data.DbDataReader.Read(); if (!nextRecord) { Close(); } } return nextRecord; } //------------------------------------------------------------------- // Attributes. public override int FieldCount { get { if (data.DbDataReader != null) return data.DbDataReader.FieldCount; return 0; } } public override bool HasRows { get { if (data.DbDataReader != null) return data.DbDataReader.HasRows; return false; } } public override int GetOrdinal (String columnName) { if (data.DbDataReader != null) return data.DbDataReader.GetOrdinal(columnName); return -1; } public override String GetDataTypeName (int columnIdx) { if (data.ColumnTypeNames != null) return data.ColumnTypeNames[columnIdx]; return String.Empty; } public override String GetName (int columnIdx) { if (data.ColumnNames != null) return data.ColumnNames[columnIdx]; return String.Empty; } public override bool IsDbNull (int columnIdx) { if (data.DbDataReader != null && data.DbDataReader.IsDBNull(columnIdx)) return true; object value = GetValue(columnIdx); return (value is System.DBNull); } public override object GetValue (int columnIdx) { if (data.DbDataReader != null) return data.DbDataReader.GetValue(columnIdx); return false; } public override bool GetBoolean (int columnIdx) { if (data.DbDataReader != null) return data.DbDataReader.GetBoolean(columnIdx); return false; } public override byte GetByte (int columnIdx) { if (data.DbDataReader != null) return data.DbDataReader.GetByte(columnIdx); return 0; } public override short GetInt16 (int columnIdx) { if (data.DbDataReader != null) return data.DbDataReader.GetInt16(columnIdx); return 0; } public override int GetInt32 (int columnIdx) { if (data.DbDataReader != null) return data.DbDataReader.GetInt32(columnIdx); return 0; } public override long GetInt64 (int columnIdx) { if (data.DbDataReader != null) return data.DbDataReader.GetInt64(columnIdx); return 0; } public override float GetFloat (int columnIdx) { if (data.DbDataReader != null) return data.DbDataReader.GetFloat(columnIdx); return 0.0f; } public override double GetDouble (int columnIdx) { if (data.DbDataReader != null) return data.DbDataReader.GetDouble(columnIdx); return 0.0; } public override decimal GetDecimal (int columnIdx) { if (data.DbDataReader != null) return data.DbDataReader.GetDecimal(columnIdx); return 0.0m; } public override String GetString (int columnIdx) { if (data.DbDataReader != null) return data.DbDataReader.GetString(columnIdx); return String.Empty; } public override DateTime GetDateTime (int columnIdx) { if (data.DbDataReader != null) return data.DbDataReader.GetDateTime(columnIdx); return DateTime.MinValue; } //------------------------------------------------------------------- } //======================================================================= }