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

namespace CommonHelpers {

//**************************************************************************************************
/// <summary>
/// </summary>
[HVolatileAccess]
public partial class HSqlOperator {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[HNotNull]
public SqlConnection Connection =>
   _Connection_;

/// <exception cref="ArgumentException" />
[DefaultValue(0)]
public int CommandTimeout
{
   get {
      return _CommandTimeout_;
   }
   set {
      if ( value < 0 )
         throw new ArgumentException();
      _CommandTimeout_ = value;
   }
}

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

/// <exception cref="ArgumentNullException" />
public HSqlOperator(SqlConnection connection)
{
   _Connection_ = HArgChecking.VerifyNotNull( connection );
}

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

/// <exception cref="ArgumentNullException" />
public int ExecuteNonQuery( string commandText ) =>
   ExecuteNonQuery( null, commandText );
/// <exception cref="ArgumentNullException" />
public int ExecuteNonQuery( string commandText, params SqlParameter[] sqlParams ) =>
   ExecuteNonQuery( null, commandText, sqlParams );
/// <exception cref="ArgumentNullException" />
public int ExecuteNonQueryFmt( string commandTextFmt, params object?[] parameters ) =>
   ExecuteNonQueryFmt( null, commandTextFmt, parameters );

/// <exception cref="ArgumentNullException" />
public int ExecuteNonQuery( [HOptional] SqlTransaction? transaction, string commandText )
{
   using (var cmd = PrepareCommand( transaction, commandText ))
      return cmd.ExecuteNonQuery();
}
/// <exception cref="ArgumentNullException" />
public int ExecuteNonQuery( [HOptional] SqlTransaction? transaction,
                            string commandText, params SqlParameter[] sqlParams )
{
   using (var cmd = PrepareCommand( transaction, commandText, sqlParams))
      return cmd.ExecuteNonQuery();
}
/// <exception cref="ArgumentNullException" />
public int ExecuteNonQueryFmt( [HOptional] SqlTransaction? transaction,
                               string commandText, params object?[] parameters ) =>
   ExecuteNonQuery( transaction, HString.FormatAsText( commandText, parameters ) );

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

/// <exception cref="ArgumentNullException" />
public SqlDataReader ExecuteReader( string commandText ) =>
   ExecuteReader( null, CommandBehavior.Default, commandText );
/// <exception cref="ArgumentNullException" />
public SqlDataReader ExecuteReader( string commandText, params SqlParameter[] sqlParams ) =>
   ExecuteReader( CommandBehavior.Default, commandText, sqlParams );
/// <exception cref="ArgumentNullException" />
public SqlDataReader ExecuteReaderFmt( string commandTextFmt, params object?[] parameters ) =>
   ExecuteReaderFmt( null, CommandBehavior.Default, commandTextFmt, parameters );

/// <exception cref="ArgumentNullException" />
public SqlDataReader ExecuteReader([HOptional] SqlTransaction? transaction,string commandText) =>
   ExecuteReader( transaction, CommandBehavior.Default, commandText );
/// <exception cref="ArgumentNullException" />
public SqlDataReader ExecuteReader( [HOptional] SqlTransaction? transaction,
                                    string commandText, params SqlParameter[] sqlParams ) =>
   ExecuteReader( transaction, CommandBehavior.Default, commandText, sqlParams );
/// <exception cref="ArgumentNullException" />
public SqlDataReader ExecuteReaderFmt( [HOptional] SqlTransaction? transaction,
                                       string commandText, params object?[] parameters ) =>
   ExecuteReaderFmt( transaction, CommandBehavior.Default, commandText, parameters );

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

/// <exception cref="ArgumentNullException" />
public SqlDataReader ExecuteReader([HOptional] CommandBehavior behaviour,string commandText) =>
   ExecuteReader( null, behaviour, commandText );
/// <exception cref="ArgumentNullException" />
public SqlDataReader ExecuteReader( [HOptional] CommandBehavior behaviour,
                                    string commandText, params SqlParameter[] sqlParams ) =>
   ExecuteReader( null, behaviour, commandText, sqlParams );
/// <exception cref="ArgumentNullException" />
public SqlDataReader ExecuteReaderFmt( [HOptional] CommandBehavior behaviour,
                                       string commandTextFmt, params object?[] parameters ) =>
   ExecuteReaderFmt( null, behaviour, commandTextFmt, parameters );

/// <exception cref="ArgumentNullException" />
public SqlDataReader ExecuteReader( [HOptional] SqlTransaction? transaction,
                                    [HOptional] CommandBehavior behaviour,
                                    string commandText )
{
   using (var cmd = PrepareCommand( transaction, commandText ))
      return cmd.ExecuteReader( behaviour );
}
/// <exception cref="ArgumentNullException" />
public SqlDataReader ExecuteReader( [HOptional] SqlTransaction? transaction,
                                    [HOptional] CommandBehavior behaviour,
                                    string commandText, params SqlParameter[] sqlParams )
{
   using (var cmd = PrepareCommand( transaction, commandText, sqlParams ))
      return cmd.ExecuteReader( behaviour );
}
/// <exception cref="ArgumentNullException" />
public SqlDataReader ExecuteReaderFmt( [HOptional] SqlTransaction? transaction,
                                       [HOptional] CommandBehavior behaviour,
                                       string commandTextFmt, params object?[] parameters ) =>
   ExecuteReader( transaction, behaviour,
      HString.FormatAsText( commandTextFmt, parameters ) );

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

/// <exception cref="ArgumentNullException" />
public SqlCommand PrepareCommand( string commandText ) =>
   PrepareCommand( null, commandText );
/// <exception cref="ArgumentNullException" />
public SqlCommand PrepareCommand( string commandText, params SqlParameter[] sqlParams ) =>
   PrepareCommand( null, commandText, sqlParams );

/// <exception cref="ArgumentNullException" />
public SqlCommand PrepareCommandFmt( string commandTextFmt, params object?[] parameters ) =>
   PrepareCommandFmt( null, commandTextFmt, parameters );

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

/// <exception cref="ArgumentNullException" />
public SqlCommand PrepareCommand( [HOptional] SqlTransaction? transaction, string commandText )
{
   HArgChecking.VerifyNotNull( commandText );
   var cmd = transaction != null ?
      new SqlCommand( commandText, Connection, transaction ) :
      new SqlCommand( commandText, Connection );
   cmd.CommandTimeout = CommandTimeout;
   return cmd;
}
/// <exception cref="ArgumentNullException" />
public SqlCommand PrepareCommand( [HOptional] SqlTransaction? transaction,
                                  string commandText, params SqlParameter[] sqlParams )
{
   HArgChecking.VerifyNotNulls( sqlParams );
   var cmd = PrepareCommand( transaction, commandText );
   foreach (var param in sqlParams)
      cmd.Parameters.Add( param );
   return cmd;
}

/// <exception cref="ArgumentNullException" />
public SqlCommand PrepareCommandFmt( [HOptional] SqlTransaction? transaction,
                                     string commandTextFmt, params object?[] parameters ) =>
   PrepareCommand( transaction, HString.FormatAsText( commandTextFmt, parameters ) );

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

volatile SqlConnection _Connection_;
volatile int _CommandTimeout_;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HSqlOperator
//**************************************************************************************************

} // CommonHelpers
