//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Data.SqlClient;

namespace CommonHelpers {

//**************************************************************************************************
partial class HQueryExecContextBase {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="InvalidOperationException" />
[HAsyncStatic]
public static Task<List<RSet_Item>> RSetToList_A<RSet_Item>( SqlDataReader dataReader,
                                                             bool closeReader = false )
where RSet_Item: new() =>
   RSetToList_A<RSet_Item>( 0, dataReader, closeReader );
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="InvalidOperationException" />
[HAsyncStatic]
public static async Task<List<RSet_Item>> RSetToList_A<RSet_Item>( int resultSetNo,
                                                                   SqlDataReader dataReader,
                                                                   bool closeReader = false )
where RSet_Item: new()
{
   HArgChecking.VerifyNotNull( dataReader );
   await EnsureConnected_A().ConfigureAwait(false);
   Action disposeReader = delegate{
      if ( closeReader ){
         dataReader.Close();
         dataReader.Dispose();
      }};
   List<RSet_Item> list;
   var curr = Current;
   curr._DataReader_ = dataReader;
   try
   {
      VerifyFieldCount( resultSetNo, dataReader );
      list = new List<RSet_Item>();
      while ( await dataReader.ReadAsync().ConfigureAwait(false) )
         list.Add( new RSet_Item() );
   }
   catch
   {
      HOps.Try( disposeReader );
      throw;
   }
   finally
   {
      curr._DataReader_ = null;
   }
   disposeReader();
   return list;
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidOperationException" />
[HAsyncStatic][HOptionalResult]
public static async Task<List<RSet_Item>?> RSetToListOrNull_A<RSet_Item>( SqlDataReader dataReader,
                                                                          bool closeReader = false )
where RSet_Item: new()
{
   HArgChecking.VerifyNotNull( dataReader );
   await EnsureConnected_A().ConfigureAwait(false);
   Action disposeReader = delegate{
      if ( closeReader ){
         dataReader.Close();
         dataReader.Dispose();
      }};
   List<RSet_Item>? list = null;
   var curr = Current;
   curr._DataReader_ = dataReader;
   try
   {
      if ( dataReader.FieldCount > 0 )
      {
         list = new List<RSet_Item>();
         while ( await dataReader.ReadAsync().ConfigureAwait(false) )
            list.Add( new RSet_Item() );
      }
   }
   catch
   {
      HOps.Try( disposeReader );
      throw;
   }
   finally
   {
      curr._DataReader_ = null;
   }
   disposeReader();
   return list;
}

//==================================================================================================

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="InvalidOperationException" />
[HAsyncStatic][HOptionalResult]
public static Task<List<RSet_Item>?> NakedDoReaderCommand_A<RSet_Item>( SqlCommand command )
where RSet_Item: new() =>
   NakedDoReaderCommandX_A<RSet_Item>( null, command );

/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidOperationException" />
[HAsyncStatic][HOptionalResult]
public static Task<List<RSet_Item>?> NakedDoReaderCommand_A<RSet_Item>( string commandText )
where RSet_Item: new() =>
   NakedDoReaderCommandX_A<RSet_Item>( null, commandText );
/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidOperationException" />
[HAsyncStatic][HOptionalResult]
public static Task<List<RSet_Item>?> NakedDoReaderCommand_A<RSet_Item>(
   string commandText, params SqlParameter[] sqlParams )
where RSet_Item: new() =>
   NakedDoReaderCommandX_A<RSet_Item>( null, commandText, sqlParams );

//--------------------------------------------------------------------------------------------------

/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidOperationException" />
[HAsyncStatic][HOptionalResult]
public static Task<List<RSet_Item>?> NakedDoReaderCommandFmt_A<RSet_Item>(
   string commandTextFmt, params object?[] parameters )
where RSet_Item: new() =>
   NakedDoReaderCommandFmtX_A<RSet_Item>( null, commandTextFmt, parameters );

//==================================================================================================

/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="InvalidOperationException" />
[HAsyncStatic][HOptionalResult]
public static async Task<List<RSet_Item>?> NakedDoReaderCommandX_A<RSet_Item>(
   [HOptional] Action? beforeScan, SqlCommand command )
where RSet_Item: new()
{
   HArgChecking.VerifyNotNull( command );
   await EnsureConnected_A().ConfigureAwait(false);
   var rdr = await HSqlCommandDispose.ExecuteReader_A( command ).ConfigureAwait(false);
   beforeScan?.Invoke();
   return await RSetToListOrNull_A<RSet_Item>( rdr, true ).ConfigureAwait(false);
}

/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidOperationException" />
[HAsyncStatic][HOptionalResult]
public static async Task<List<RSet_Item>?> NakedDoReaderCommandX_A<RSet_Item>(
   [HOptional] Action? beforeScan, string commandText )
where RSet_Item: new()
{
   HArgChecking.VerifyNotNull( commandText );
   await EnsureConnected_A().ConfigureAwait(false);
   var rdr = await new HSqlOperator(Connection).ExecuteReader_A(
      OuterTransaction, commandText ).ConfigureAwait(false);
   beforeScan?.Invoke();
   return await RSetToListOrNull_A<RSet_Item>( rdr, true ).ConfigureAwait(false);
}
/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidOperationException" />
[HAsyncStatic][HOptionalResult]
public static async Task<List<RSet_Item>?> NakedDoReaderCommandX_A<RSet_Item>(
   [HOptional] Action? beforeScan, string commandText, params SqlParameter[] sqlParams )
where RSet_Item: new()
{
   HArgChecking.VerifyNotNulls( commandText, sqlParams );
   await EnsureConnected_A().ConfigureAwait(false);
   var rdr = await new HSqlOperator(Connection).ExecuteReader_A(
      OuterTransaction, commandText, sqlParams ).ConfigureAwait(false);
   beforeScan?.Invoke();
   return await RSetToListOrNull_A<RSet_Item>( rdr, true ).ConfigureAwait(false);
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="ArgumentNullException" />
/// <exception cref="InvalidOperationException" />
[HAsyncStatic][HOptionalResult]
public static async Task<List<RSet_Item>?> NakedDoReaderCommandFmtX_A<RSet_Item>(
   [HOptional] Action? beforeScan, string commandTextFmt, params object?[] parameters )
where RSet_Item: new()
{
   HArgChecking.VerifyNotNulls( commandTextFmt, parameters );
   await EnsureConnected_A().ConfigureAwait(false);
   var rdr = await new HSqlOperator(Connection).ExecuteReaderFmt_A(
      OuterTransaction, commandTextFmt, parameters ).ConfigureAwait(false);
   beforeScan?.Invoke();
   return await RSetToListOrNull_A<RSet_Item>( rdr, true ).ConfigureAwait(false);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HQueryExecContextBase
//**************************************************************************************************

} // CommonHelpers
