static class SqlExec
{
public static void ExecCommandBatch(System.Data.Common.DbConnection conn, System.Data.IsolationLevel isolation, ExceptionFailSafeEventHandler<System.Exception> failSafe, params System.Data.Common.DbCommand[] cmds)
{
if ((conn == null))
throw new System.ArgumentNullException("conn");
if ((cmds.Length < 2))
throw new System.ArgumentException("Must supply more than one Command");
// TODO: validate isolation?
bool success = false;
BatchCommandFailedException excp = null;
ExceptionFailSafeEventArgs<System.Exception> args = new ExceptionFailSafeEventArgs<System.Exception>();
int totalAffectedRows = 0;
int length = cmds.Length - 1;
int i;
if ((conn.State != ConnectionState.Open))
conn.Open();
DbTransaction trans;
try
{
trans = conn.BeginTransaction(isolation);
}
catch (System.Exception ex)
{
trans = conn.BeginTransaction();
}
for (i = 0; i <= length; i++)
{
cmds[i].Connection = conn;
cmds[i].Transaction = trans;
}
try
{
for (i = 0; i <= length; i++)
{
totalAffectedRows += cmds[i].ExecuteNonQuery();
}
success = true;
}
catch (System.Exception ex)
{
excp = new BatchCommandFailedException(cmds[i], i, ex);
}
finally
{
if (success)
{
trans.Commit();
}
else
{
trans.Rollback();
totalAffectedRows = 0;
args.Exception = excp.InnerException;
if (failSafe != null)
failSafe.Invoke(typeof(SqlExec), args);
}
trans.Dispose();
foreach (DbCommand cmd in cmds)
{
cmd.Dispose();
}
conn.Close();
conn.Dispose();
if (excp != null)
if (args.Throw)
throw excp;
}
//Return totalAffectedRows?
}
}
public delegate void ExceptionFailSafeEventHandler<T>(object sender, ExceptionFailSafeEventArgs<T> e) where T : System.Exception;
public class ExceptionFailSafeEventArgs<T> : System.EventArgs where T : System.Exception
{
private T _data;
private bool _throw = true;
public bool Throw
{
get { return _throw; }
set { _throw = value; }
}
public ExceptionFailSafeEventArgs()
: this(null) { }
public ExceptionFailSafeEventArgs(T ex)
: base()
{ _data = ex; }
public T Exception
{
get { return _data; }
set { _data = value; }
}
}
[Serializable()]
public class BatchCommandFailedException : DbException
{
public BatchCommandFailedException(string message)
: base("Command execution has failed. Reason: " + message){ }
public BatchCommandFailedException(string message, DbCommand cmd)
: base(string.Format("Command execution for command '{0}' has failed. Reason: " + message, cmd.CommandText)){ }
public BatchCommandFailedException(DbCommand cmd)
: base(string.Format("Command execution for command '{0}' has failed.", cmd.CommandText)){ }
public BatchCommandFailedException(DbCommand cmd, int ordinal)
: base(string.Format("Command execution for command {0}: '{1}' has failed.", ordinal, cmd.CommandText)){ }
public BatchCommandFailedException(DbCommand cmd, int ordinal, Exception inner)
: base(string.Format("Command execution for command {0}: '{1}' has failed. Reason: {2}", ordinal, cmd.CommandText, inner.Message), inner){ }
public BatchCommandFailedException(string message, Exception inner)
: base(message, inner){ }
public BatchCommandFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
: base(info, context){ }
}
Refactorings
No refactoring yet !
Pablo
November 7, 2007, November 07, 2007 11:54, permalink
Refactor my code
Public Shared Function FromNumBase(ByVal num As String, _
ByVal base As Integer) As ULong
Const aMay As Integer = AscW("A") - 10
Const aMin As Integer = AscW("a") - 10
Dim i As Integer = 0
Dim n As ULong = 0
num = num.TrimStart("0".ToCharArray)
For j As Integer = num.Length - 1 To 0 Step -1
Select Case num(j).ToString
Case "0"
i += 1
Case " "
' nada
Case "1" To "9"
Dim k As Integer = CInt(num(j).ToString)
If k - base >= 0 Then Continue For
'n = CULng(n + k * System.Math.Pow(base, i))
n = n + CULng(k * System.Math.Pow(base, i))
i += 1
Case "A" To "Z"
Dim k As Integer = AscW(num(j)) - aMay
If k - base >= 0 Then Continue For
'n = CULng(n + k * System.Math.Pow(base, i))
n = n + CULng(k * System.Math.Pow(base, i))
i += 1
Case "a" To "z"
Dim k As Integer = AscW(num(j)) - aMin
If k - base >= 0 Then Continue For
'n = CULng(n + k * System.Math.Pow(base, i))
n = n + CULng(k * System.Math.Pow(base, i))
i += 1
End Select
Next
Return n
End Function
It's rather large, but also rather simple.
The actual implementation has several overloads; it also doesn't seem to roll back every command.