} // FillFirst public virtual void FillFirst <T>(ConnectionWrapper oConnectionToUse, T oInstance, string sQuery, CommandSpecies nSpecies, params QueryParameter[] aryParams) { if (!typeof(T).IsValueType) { // Plain comparison "oInstance == null" fires warning "possible compare of value type with null". // Assignment to temp variable is a workaround to suppress the warning. // And if we are already here then T is not a value type so it can be null. object obj = oInstance; if (obj == null) { throw new NullReferenceException("Cannot FillFirst of type " + typeof(T) + ": no instance specified."); } } // if ForEachRowSafe( oConnectionToUse, (sr, bRowsetStart) => { sr.Fill(oInstance); return(ActionResult.SkipAll); }, sQuery, nSpecies, aryParams ); } // FillFirst
} // FillFirst public virtual void FillFirst <T>(ConnectionWrapper oConnectionToUse, T oInstance) { if (!typeof(T).IsValueType) { // Plain comparison "oInstance == null" fires warning "possible compare of value type with null". // Assignment to temp variable is a workaround to suppress the warning. // And if we are already here then T is not a value type so it can be null. object obj = oInstance; if (obj == null) { throw new NullReferenceException("Cannot FillFirst of type " + typeof(T) + ": no instance specified."); } } // if if (!IsReadyToGo()) { throw new ArgumentOutOfRangeException("Parameters are invalid for " + GetName(), (Exception)null); } QueryParameter[] args = PrepareParameters(); DB.FillFirst(oConnectionToUse, oInstance, GetName(), Species, args); FillOutputs(args); } // FillFirst
} // ForEachRowSafe public virtual void ForEachRowSafe(ConnectionWrapper oConnectionToUse, Action <SafeReader> oAction) { ForEachRowSafe(oConnectionToUse, (sr, bRowsetStart) => { oAction(sr); return(ActionResult.Continue); }); } // ForEachRowSafe
public virtual void ForEachRow(ConnectionWrapper oConnectionToUse, Action <DbDataReader> oAction, string sQuery, params QueryParameter[] aryParams) { if (ReferenceEquals(oAction, null)) { throw new DbException("Callback action not specified in 'ForEachRow' call."); } ForEachRow(oConnectionToUse, oAction, sQuery, CommandSpecies.Auto, aryParams); } // ForEachRow
} // ForEachRow public virtual void ForEachRow(ConnectionWrapper oConnectionToUse, Func <DbDataReader, bool, ActionResult> oAction, string sQuery, CommandSpecies nSpecies, params QueryParameter[] aryParams) { if (ReferenceEquals(oAction, null)) { throw new DbException("Callback action not specified in 'ForEachRow' call."); } Run(oConnectionToUse, oAction, ExecMode.ForEachRow, nSpecies, sQuery, aryParams); } // ForEachRow
} // FillFirst /// <summary> /// Does not support object properties for output values! /// </summary> /// <param name="oConnectionToUse"></param> /// <returns></returns> public virtual IEnumerable <SafeReader> ExecuteEnumerable(ConnectionWrapper oConnectionToUse = null) { if (!IsReadyToGo()) { throw new ArgumentOutOfRangeException("Parameters are invalid for " + GetName(), (Exception)null); } return(DB.ExecuteEnumerable(oConnectionToUse, GetName(), Species, PrepareParameters())); } // ExecuteEnumerable
} // PublishRunningTime protected virtual object Run( ConnectionWrapper cw, ExecMode nMode, CommandSpecies nSpecies, string spName, params QueryParameter[] aryParams ) { return(Run(cw, null, nMode, nSpecies, spName, aryParams)); } // Run
} // ExecuteScalar public virtual T ExecuteScalar <T>(ConnectionWrapper oConnectionToUse, string sQuery, CommandSpecies nSpecies, params QueryParameter[] aryParams) { object oRes = Run(oConnectionToUse, ExecMode.Scalar, nSpecies, sQuery, aryParams); if ((oRes == null) || (oRes is DBNull)) { return(default(T)); } return((T)oRes); } // ExecuteScalar
} // ForEachRow public virtual void ForEachRow(ConnectionWrapper oConnectionToUse, Func <DbDataReader, bool, ActionResult> oAction) { if (!IsReadyToGo()) { throw new ArgumentOutOfRangeException("Parameters are invalid for " + GetName(), (Exception)null); } QueryParameter[] args = PrepareParameters(); DB.ForEachRow(oConnectionToUse, oAction, GetName(), Species, args); FillOutputs(args); } // ForEachRow
} // ForEachResult public virtual void ForEachResult(ConnectionWrapper oConnectionToUse, Func <IResultRow, ActionResult> oAction) { if (!IsReadyToGo()) { throw new ArgumentOutOfRangeException("Parameters are invalid for " + GetName(), (Exception)null); } if (oAction == null) { throw new ArgumentNullException("oAction", "No action specified for 'ForEachResult' call."); } var oResultRowType = GetType().GetNestedType("ResultRow", BindingFlags.Public); if (oResultRowType == null) { throw new NotImplementedException("This class does not have a nested public ResultRow class."); } if (null == oResultRowType.GetInterface(typeof(IResultRow).ToString())) { throw new NotImplementedException("Nested ResultRow class does not implement " + typeof(IResultRow)); } var oConstructorInfo = oResultRowType.GetConstructors().FirstOrDefault(ci => ci.GetParameters().Length == 0); if (oConstructorInfo == null) { throw new NotImplementedException("Nested ResultRow class has no parameterless constructor."); } QueryParameter[] args = PrepareParameters(); DB.ForEachRowSafe( oConnectionToUse, (sr, bRowsetStart) => { var oRow = (IResultRow)oConstructorInfo.Invoke(null); oRow.SetIsFirst(bRowsetStart); sr.Fill(oRow); return(oAction(oRow)); }, GetName(), Species, args ); FillOutputs(args); } // ForEachResult
} // ForEachResult public virtual void ForEachResult <T>(ConnectionWrapper oConnectionToUse, Action <T> oAction, string sQuery, CommandSpecies nSpecies, params QueryParameter[] aryParams) where T : IResultRow, new() { if (ReferenceEquals(oAction, null)) { throw new DbException("Callback action not specified in 'ForEachResult' call."); } Func <T, ActionResult> oFunc = r => { oAction(r); return(ActionResult.Continue); }; ForEachResult(oConnectionToUse, oFunc, sQuery, nSpecies, aryParams); } // ForEachResult
} // ForEachRow public virtual void ForEachRow(ConnectionWrapper oConnectionToUse, Action <DbDataReader> oAction, string sQuery, CommandSpecies nSpecies, params QueryParameter[] aryParams) { if (ReferenceEquals(oAction, null)) { throw new DbException("Callback action not specified in 'ForEachRow' call."); } Func <DbDataReader, bool, ActionResult> oFunc = (r, bRowsetStart) => { oAction(r); return(ActionResult.Continue); }; ForEachRow(oConnectionToUse, oFunc, sQuery, nSpecies, aryParams); } // ForEachRow
} // Fill public virtual T FillFirst <T>(ConnectionWrapper oConnectionToUse = null) where T : new() { if (!IsReadyToGo()) { throw new ArgumentOutOfRangeException("Parameters are invalid for " + GetName(), (Exception)null); } QueryParameter[] args = PrepareParameters(); T res = DB.FillFirst <T>(oConnectionToUse, GetName(), Species, args); FillOutputs(args); return(res); } // FillFirst
} // ExecuteScalar public virtual int ExecuteNonQuery(ConnectionWrapper oConnectionToUse = null) { if (!IsReadyToGo()) { throw new ArgumentOutOfRangeException("Parameters are invalid for " + GetName(), (Exception)null); } QueryParameter[] args = PrepareParameters(); int result = DB.ExecuteNonQuery(oConnectionToUse, GetName(), Species, args); FillOutputs(args); return(result); } // ExecuteNonQuery
} // ExecuteEnumerable public virtual SafeReader GetFirst(ConnectionWrapper oConnectionToUse = null) { if (!IsReadyToGo()) { throw new ArgumentOutOfRangeException("Parameters are invalid for " + GetName(), (Exception)null); } QueryParameter[] args = PrepareParameters(); SafeReader res = DB.GetFirst(oConnectionToUse, GetName(), Species, args); FillOutputs(args); return(res); } // GetFirst
public virtual void DisposeAfterOneUsage(bool bAllesInOrdnung, ConnectionWrapper oConnection) { if (oConnection == null) { return; } if (bAllesInOrdnung) { ms_oPool.Take(oConnection.Pooled); } else { ms_oPool.Drop(oConnection.Pooled); } } // DisposeAfterOneUsage
} // Fill public List <T> Fill <T>(ConnectionWrapper oConnectionToUse, string sQuery, CommandSpecies nSpecies, params QueryParameter[] aryParams) where T : new() { var oResult = new List <T>(); ForEachRowSafe( oConnectionToUse, (sr, bRowsetStart) => { oResult.Add(sr.Fill <T>()); return(ActionResult.Continue); }, sQuery, nSpecies, aryParams ); return(oResult); } // Fill
} // FillFirst public virtual T FillFirst <T>(ConnectionWrapper oConnectionToUse, string sQuery, CommandSpecies nSpecies, params QueryParameter[] aryParams) where T : new() { var oResult = new T(); ForEachRowSafe( oConnectionToUse, (sr, bRowsetStart) => { sr.Fill(oResult); return(ActionResult.SkipAll); }, sQuery, nSpecies, aryParams ); return(oResult); } // FillFirst
} // GetFirst public virtual SafeReader GetFirst(ConnectionWrapper oConnectionToUse, string sQuery, CommandSpecies nSpecies, params QueryParameter[] aryParams) { SafeReader oResult = null; ForEachRowSafe( oConnectionToUse, (sr, bRowsetStart) => { oResult = sr.ToCache(); return(ActionResult.SkipAll); }, sQuery, nSpecies, aryParams ); return(oResult ?? SafeReader.CreateEmpty()); } // GetFirst
} // ForEachResult public static IEnumerable <SafeReader> ExecuteEnumerable( this DbCommand command, ConnectionWrapper cw, AConnection oConnection, Action oLogExecution = null ) { bool bAllesInOrdnung = false; try { cw.Open(); DbDataReader oReader = command.ExecuteReader(); if (oLogExecution != null) { oLogExecution(); } do { if (!oReader.HasRows) { continue; } while (oReader.Read()) { yield return(new SafeReader(oReader)); } } while (oReader.NextResult()); oReader.Close(); bAllesInOrdnung = true; } finally { if (oConnection != null) { oConnection.DisposeAfterOneUsage(bAllesInOrdnung, cw); } } // try } // ExecuteEnumerable
} // ForEachResult public virtual void ForEachResult <T>(ConnectionWrapper oConnectionToUse, Func <T, ActionResult> oAction, string sQuery, CommandSpecies nSpecies, params QueryParameter[] aryParams) where T : IResultRow, new() { if (ReferenceEquals(oAction, null)) { throw new DbException("Callback action not specified in 'ForEachResult' call."); } ForEachRowSafe( oConnectionToUse, (sr, bRowsetStart) => { var oResult = new T(); oResult.SetIsFirst(bRowsetStart); sr.Fill(oResult); return(oAction(oResult)); }, sQuery, nSpecies, aryParams ); } // ForEachResult
} // ExecuteNonQuery public virtual int ExecuteNonQuery(ConnectionWrapper oConnectionToUse, string sQuery, CommandSpecies nSpecies, params QueryParameter[] aryParams) { return((int)Run(oConnectionToUse, ExecMode.NonQuery, nSpecies, sQuery, aryParams)); } // ExecuteNonQuery
} // Fill public virtual T FillFirst <T>(ConnectionWrapper oConnectionToUse, string sQuery, params QueryParameter[] aryParams) where T : new() { return(FillFirst <T>(oConnectionToUse, sQuery, CommandSpecies.Auto, aryParams)); } // FillFirst
} // FillFirst public virtual SafeReader GetFirst(ConnectionWrapper oConnectionToUse, string sQuery, params QueryParameter[] aryParams) { return(GetFirst(oConnectionToUse, sQuery, CommandSpecies.Auto, aryParams)); } // GetFirst
} // Run protected virtual object Run( ConnectionWrapper cw, Func <DbDataReader, bool, ActionResult> oAction, ExecMode nMode, CommandSpecies nSpecies, string spName, params QueryParameter[] aryParams ) { if ((nMode == ExecMode.ForEachRow) && ReferenceEquals(oAction, null)) { throw new DbException("Callback action not specified in 'ForEachRow' call."); } var oArgsForLog = new StringBuilder(); LogVerbosityLevel nLogVerbosityLevel = LogVerbosityLevel; foreach (QueryParameter prm in aryParams) { oArgsForLog.Append(oArgsForLog.Length > 0 ? ", " : string.Empty).Append(prm); } string sArgsForLog = "(" + oArgsForLog + ")"; Guid guid = Guid.NewGuid(); if (nLogVerbosityLevel == LogVerbosityLevel.Verbose) { Log.Debug("Starting to run query:\n\tid = {0}\n\t{1}{2}", guid, spName, sArgsForLog); } SqlRetryer oRetryer = CreateRetryer(); oRetryer.LogVerbosityLevel = this.LogVerbosityLevel; DbCommand oCmdToDispose = null; try { DbCommand cmd = BuildCommand(spName, nSpecies, aryParams); oCmdToDispose = cmd; object oResult = null; oRetryer.Retry(() => oResult = RunOnce(cw, oAction, nMode, cmd, nLogVerbosityLevel, spName, sArgsForLog, guid) ); // Retry return(oResult); } catch (Exception e) { if (nLogVerbosityLevel == LogVerbosityLevel.Verbose) { Log.Error(e, "Error while executing query {0}", guid); } else { Log.Error(e, "Error while executing query:\n\tid = {0}\n\t{1}{2}", guid, spName, sArgsForLog); } throw; } finally { if (oCmdToDispose != null) { oCmdToDispose.Dispose(); if (nLogVerbosityLevel == LogVerbosityLevel.Verbose) { Log.Debug("Command has been disposed."); } } // if } // try } // Run
} // Run protected virtual object RunOnce( ConnectionWrapper oConnectionToUse, Func <DbDataReader, bool, ActionResult> oAction, ExecMode nMode, DbCommand command, LogVerbosityLevel nLogVerbosityLevel, string spName, string sArgsForLog, Guid guid ) { ConnectionWrapper oConnection = null; bool bAllesInOrdnung = true; bool bDropAfterUse = oConnectionToUse == null; try { oConnection = oConnectionToUse ?? TakeFromPool(); if (oConnection == null) { throw new NullReferenceException("There is no available connection to execute the query."); } command.Connection = oConnection.Connection; if (oConnection.Transaction != null) { command.Transaction = oConnection.Transaction; } string sPooledConID = oConnection.Pooled.Name; var sw = new Stopwatch(); sw.Start(); switch (nMode) { case ExecMode.Scalar: oConnection.Open(); object value = command.ExecuteScalar(); PublishRunningTime(sPooledConID, nLogVerbosityLevel, spName, sArgsForLog, guid, sw); return(value); case ExecMode.Reader: oConnection.Open(); var oReader = command.ExecuteReader(); long nPrevStopwatchValue = sw.ElapsedMilliseconds; if (nLogVerbosityLevel == LogVerbosityLevel.Verbose) { PublishRunningTime(sPooledConID, nLogVerbosityLevel, spName, sArgsForLog, guid, sw); } var dataTable = new DataTable(); dataTable.Load(oReader); string sMsg; switch (nLogVerbosityLevel) { case LogVerbosityLevel.Compact: sMsg = "completed and data loaded"; break; case LogVerbosityLevel.Verbose: sMsg = "data loaded"; break; default: throw new ArgumentOutOfRangeException(); } // switch PublishRunningTime(sPooledConID, nLogVerbosityLevel, spName, sArgsForLog, guid, sw, nPrevStopwatchValue, sMsg); oReader.Close(); return(dataTable); case ExecMode.NonQuery: oConnection.Open(); int nResult = command.ExecuteNonQuery(); string sResult = ((nResult == 0) || (nResult == -1)) ? "no" : nResult.ToString(CultureInfo.InvariantCulture); PublishRunningTime(sPooledConID, nLogVerbosityLevel, spName, sArgsForLog, guid, sw, sAuxMsg: string.Format("- {0} row{1} changed", sResult, nResult == 1 ? "" : "s")); return(nResult); case ExecMode.ForEachRow: oConnection.Open(); command.ForEachRow(oAction, () => PublishRunningTime(sPooledConID, nLogVerbosityLevel, spName, sArgsForLog, guid, sw)); return(null); case ExecMode.Enumerable: return(command.ExecuteEnumerable( oConnection, bDropAfterUse ? this : null, () => PublishRunningTime(sPooledConID, nLogVerbosityLevel, spName, sArgsForLog, guid, sw) )); default: throw new ArgumentOutOfRangeException("nMode"); } // switch } catch (Exception) { bAllesInOrdnung = false; throw; } finally { if (bDropAfterUse && (nMode != ExecMode.Enumerable)) { DisposeAfterOneUsage(bAllesInOrdnung, oConnection); } } // try } // RunOnce
} // DisposeAfterOneUsage public virtual IEnumerable <SafeReader> ExecuteEnumerable(ConnectionWrapper oConnectionToUse, string sQuery, params QueryParameter[] aryParams) { return(ExecuteEnumerable(oConnectionToUse, sQuery, CommandSpecies.Auto, aryParams)); } // ExecuteEnumerable
} // ExecuteEnumerable public virtual IEnumerable <SafeReader> ExecuteEnumerable(ConnectionWrapper oConnectionToUse, string sQuery, CommandSpecies nSpecies, params QueryParameter[] aryParams) { return((IEnumerable <SafeReader>)Run(oConnectionToUse, null, ExecMode.Enumerable, nSpecies, sQuery, aryParams)); } // ExecuteEnumerable
} // ExecuteEnumerable public virtual int ExecuteNonQuery(ConnectionWrapper oConnectionToUse, string sQuery, params QueryParameter[] aryParams) { return(ExecuteNonQuery(oConnectionToUse, sQuery, CommandSpecies.Auto, aryParams)); } // ExecuteNonQuery
public virtual void ForEachResult <T>(ConnectionWrapper oConnectionToUse, Action <T> oAction, string sQuery, params QueryParameter[] aryParams) where T : IResultRow, new() { ForEachResult <T>(oConnectionToUse, oAction, sQuery, CommandSpecies.Auto, aryParams); } // ForEachResult