internal static void ExecuteBulkInsert(Connectable connectable, SqlConnection cn) { var bulkArguments = connectable.Executable.Arguments .Where(argument => argument.IsBulk) .ToList(); if (bulkArguments.Count == 0) { return; } var empty = bulkArguments.Where(argument => Value.IsNull(argument.Value)) .FirstOrDefault(); if (empty != null) { throw new QueryTalkException("Importer.ExecuteBulkInsert", QueryTalkExceptionType.ParamArgumentNull, String.Format("param = {0}", empty.ParamName), Text.Method.Pass); } using (SqlBulkCopy bulkCopy = new SqlBulkCopy(cn)) { bulkArguments.ForEach(argument => { if (((DataTable)argument.Value).Rows.Count > 0) { bulkCopy.DestinationTableName = argument.ParamName; bulkCopy.WriteToServer((DataTable)argument.Value); } }); } }
private Connectable Build() { // use original executable object var executable = _connectable.Executable; // set testing params SetTestingParameters(executable); // create new connectable object (using the original executable) var connectable = new Connectable( _connectable.Client, executable, _connectable.ConnectionStringAsync, _sql.Text); connectable.SetTimeout(_connectable.CommandTimeout); // wrap final SQL by BEGIN TRANSACTION/ROLLBACK block connectable.Sql = Wall.Text.GenerateSql(1000) .Append(Wall.Text.Free.BeginTestTransaction) .NewLine() .NewLine(connectable.Sql) .NewLine(Wall.Text.Free.EndQueryTalkCode) .NewLine(Wall.Text.Free.EndTestTransaction) .ToString(); return(connectable); }
internal static Async <Result <T1, T2, T3, T4, T5, T6, T7, T8, T9> > LoadManyAsync <T1, T2, T3, T4, T5, T6, T7, T8, T9>( Connectable connectable) { var async = new Async <Result <T1, T2, T3, T4, T5, T6, T7, T8, T9> >(connectable); async.Result = new Result <T1, T2, T3, T4, T5, T6, T7, T8, T9>(connectable); Type currentTableType = typeof(T1); int tableIndex = 0; Func <IDataReader, TableSetLoaderArgs> tableSetLoader = (reader) => { async.Result.Table1 = ReadFirstOrNextTable <T1>(reader, connectable, ref tableIndex); currentTableType = typeof(T2); async.Result.Table2 = ReadFirstOrNextTable <T2>(reader, connectable, ref tableIndex); currentTableType = typeof(T3); async.Result.Table3 = ReadFirstOrNextTable <T3>(reader, connectable, ref tableIndex); currentTableType = typeof(T4); async.Result.Table4 = ReadFirstOrNextTable <T4>(reader, connectable, ref tableIndex); currentTableType = typeof(T5); async.Result.Table5 = ReadFirstOrNextTable <T5>(reader, connectable, ref tableIndex); currentTableType = typeof(T6); async.Result.Table6 = ReadFirstOrNextTable <T6>(reader, connectable, ref tableIndex); currentTableType = typeof(T7); async.Result.Table7 = ReadFirstOrNextTable <T7>(reader, connectable, ref tableIndex); currentTableType = typeof(T8); async.Result.Table8 = ReadFirstOrNextTable <T8>(reader, connectable, ref tableIndex); currentTableType = typeof(T9); async.Result.Table9 = ReadFirstOrNextTable <T9>(reader, connectable, ref tableIndex); return(null); }; _LoadTableSetBodyAsync(connectable, tableSetLoader, async, currentTableType); return(async); }
internal static Connectable GetConnectable(Assembly client, Chainer prev, ConnectionData connectionData) { if (prev is Connectable) { return((Connectable)prev); } Connectable connectable; Compilable compilable = null; Executable executable = null; if (prev is Compilable) { compilable = (Compilable)prev; executable = new Executable(compilable); } else if (prev is IExecutable) { executable = ((Chainer)prev).Executable; } else if (prev is Connectable) { connectable = (Connectable)prev; connectable.SetTimeout(connectionData.CommandTimeout); } // root: else { compilable = new Procedure(prev); executable = new Executable(compilable); } connectable = new Connectable(client, executable, connectionData); return(connectable); }
internal static Result <T1, T2, T3, T4, T5> LoadMany <T1, T2, T3, T4, T5>(Connectable connectable) { int returnValue; var result = new Result <T1, T2, T3, T4, T5>(connectable); Type currentTableType = typeof(T1); int tableIndex = 0; Func <IDataReader, TableSetLoaderArgs> tableSetLoader = (reader) => { result.Table1 = ReadFirstOrNextTable <T1>(reader, connectable, ref tableIndex); currentTableType = typeof(T2); result.Table2 = ReadFirstOrNextTable <T2>(reader, connectable, ref tableIndex); currentTableType = typeof(T3); result.Table3 = ReadFirstOrNextTable <T3>(reader, connectable, ref tableIndex); currentTableType = typeof(T4); result.Table4 = ReadFirstOrNextTable <T4>(reader, connectable, ref tableIndex); currentTableType = typeof(T5); result.Table5 = ReadFirstOrNextTable <T5>(reader, connectable, ref tableIndex); return(null); }; _LoadTableSetBody(connectable, tableSetLoader, currentTableType, out returnValue); result.ReturnValue = returnValue; return(result); }
private static ResultSet <T> ReadFirstOrNextTable <T>( IDataReader reader, Connectable connectable, ref int tableIndex ) { return(_Read <T>(reader, connectable, null, ref tableIndex, tableIndex == 0)); }
internal static void TryThrowException(QueryTalkException exception, Connectable connectable) { if (exception != null) { exception.ObjectName = ((IName)connectable.Executable).Name; exception.Method = Text.Method.Go; throw exception; } }
private static QueryTalkException NoMoreResultsetException <T>(Connectable connectable) { return(new QueryTalkException( "Reader.NoMoreResultsetException", QueryTalkExceptionType.NoMoreResultset, ((IName)connectable.Executable).Name, Text.Method.Go, String.Format("superfluous table = {0}", typeof(T)))); }
internal static Result <T> LoadDataTable <T>(Connectable connectable, bool allowEmpty = false) { DataSet dataSet = new DataSet(); dataSet.Locale = System.Globalization.CultureInfo.InvariantCulture; int returnValue = 0; Result <T> result = null; try { using (SqlConnection cn = new SqlConnection(connectable.ConnectionString)) { cn.Open(); Importer.ExecuteBulkInsert(connectable, cn); var cmd = new SqlCommand(connectable.Sql, cn); SqlDataAdapter da = new SqlDataAdapter(cmd); da.SelectCommand.CommandTimeout = connectable.CommandTimeout; da.Fill(dataSet); int tableCount = dataSet.Tables.Count; DataTable firstTable = null; if (tableCount != 0) { firstTable = dataSet.Tables[0]; if (tableCount <= 1) { if (!allowEmpty) { throw new QueryTalkException("Reader.LoadDataTable", QueryTalkExceptionType.NoMoreResultset, "table = DataTable", Text.Method.Go); } } // get return value DataTable lastTable = dataSet.Tables[tableCount - 1]; var value = lastTable.Rows[0][Text.Reserved.ReturnValueColumnName]; if (value != null && value.GetType() == typeof(System.Int32)) { returnValue = (int)value; } } result = new Result <T>(connectable, firstTable); result.ReturnValue = returnValue; } } catch (QueryTalkException ex) { ex.ObjectName = ((IName)connectable.Executable).Name; ex.Method = Text.Method.Go; throw; } return(result); }
internal static DataTable LoadDataTable <T>(Connectable connectable, IDataReader reader) { DataTable table = new DataTable(); table.Locale = System.Globalization.CultureInfo.InvariantCulture; try { DataTable schema = reader.GetSchemaTable(); foreach (DataRow row in schema.Rows) { DataColumn column = new DataColumn(); column.ColumnName = row["ColumnName"].ToString(); column.DataType = Type.GetType(row["DataType"].ToString()); table.Columns.Add(column); } if (reader.Read()) { if (reader.GetName(0) == Text.Reserved.ReturnValueColumnName) { throw new QueryTalkException("Reader.LoadDataTable", QueryTalkExceptionType.NoMoreResultset, "table = DataTable", Text.Method.Go); } } else { return(table); } int rowix = 1; do { DataRow row = table.NewRow(); for (int i = 0; i < table.Columns.Count; i++) { row[i] = reader[i]; } table.Rows.Add(row); if (connectable.AsyncCanceled) { ThrowOperationCancelledByUserException <T>(connectable, rowix); } ++rowix; }while (reader.Read()); } catch (QueryTalkException ex) { ex.ObjectName = ((IName)connectable.Executable).Name; ex.Method = Text.Method.Go; throw; } return(table); }
private static int ReadOutputDataOnFound(IDataReader reader, Connectable connectable) { Value[] values = Common.DefaultReturnValue; // double check if (!reader.Read()) { return(0); } try { int count = reader.FieldCount; values = new Value[count]; var outputArguments = ParameterArgument.GetOutputArguments(connectable.Executable.Arguments); for (int i = 0; i < count; ++i) { Value outputData = new Value(reader.GetValue(i)); values[i] = outputData; // output values: if (i >= 1) { outputArguments[i - 1].SetOutput(outputData.Original); } } connectable.OutputArguments = outputArguments; int returnValue = 0; if (values[0] != null) { int retval; if (int.TryParse(values[0].ToString(), out retval)) { returnValue = retval; } else { ThrowQueryTalkReservedNameException(); } } connectable.ReturnValue = returnValue; return(returnValue); } catch (QueryTalkException) { throw; } catch (System.Exception ex) { throw ClrException(ex, "ReadOutputDataOnFound", connectable, null); } }
internal static void ThrowOperationCancelledByUserException <T>(Connectable connectable, int rowix) { throw new QueryTalkException( "Reader.ThrowOperationCancelledByUserException", QueryTalkExceptionType.OperationCanceledByUser, ((IName)connectable.Executable).Name, null, String.Format("terminated table = {0}{1} at row = {2}", typeof(T), Environment.NewLine, rowix)); }
private static IEnumerable <T> _LoadTable <T>( Connectable connectable, IDataReader reader, bool allowEmpty = false) { Type type = typeof(T); var table = new HashSet <T>(); Func <IDataRecord, T> loader = null; if (!reader.Read()) { return(table); } if (reader.GetName(0) == Text.Reserved.ReturnValueColumnName) { if (reader.NextResult()) { Reader.ThrowQueryTalkReservedNameException(); } if (!allowEmpty) { throw new QueryTalkException("Reader._LoadTable<T>", QueryTalkExceptionType.NoMoreResultset, String.Format("table = {0}", type), Text.Method.Go); } else { return(null); } } QueryTalkException exception; loader = Loader.ProvideLoader <T>(reader, out exception); Loader.TryThrowException(exception, connectable); int rowix = 1; do { T row = loader(reader); table.Add(row); if (connectable.AsyncCanceled) { ThrowOperationCancelledByUserException <T>(connectable, rowix); } ++rowix; }while (reader.Read()); Loader.SetTableAsLoaded(table); return(table); }
internal static QueryTalkException ClrException( System.Exception ex, string readerName, Connectable connectable, string method, string arguments = null) { QueryTalkException exception = new QueryTalkException(String.Format("{0}.{1}", Text.Free.Reader, readerName), QueryTalkExceptionType.ClrException, ((IName)connectable).Name, method, arguments); exception.ClrException = ex; return(exception); }
private static ResultSet <dynamic> GetOutputValues(Connectable connectable, Result result) { List <dynamic> values = new List <dynamic>(); values.Add(new OutputValue(Wall.Text.Reserved.ReturnValue, result.ReturnValue)); if (connectable.OutputArguments != null) { foreach (var argument in connectable.OutputArguments) { values.Add(new OutputValue(argument.ParamName, ((Value)argument.Original).Original)); } } return(new ResultSet <dynamic>(values)); }
// core load method for sync/async load private static IEnumerable <T> _load <T>(Connectable connectable, IDataReader reader, Action <T> rowHandler, bool allowEmpty = false) { if (connectable.IgnoreLoad) { return(null); } if (rowHandler == null) { var table = _LoadTable <T>(connectable, reader, allowEmpty); return(table); } else { _EnumerateTable <T>(connectable, reader, rowHandler); return(null); } }
internal static Async <Result <T1, T2> > LoadManyAsync <T1, T2>(Connectable connectable) { var async = new Async <Result <T1, T2> >(connectable); async.Result = new Result <T1, T2>(connectable); Type currentTableType = typeof(T1); int tableIndex = 0; Func <IDataReader, TableSetLoaderArgs> tableSetLoader = (reader) => { async.Result.Table1 = ReadFirstOrNextTable <T1>(reader, connectable, ref tableIndex); currentTableType = typeof(T2); async.Result.Table2 = ReadFirstOrNextTable <T2>(reader, connectable, ref tableIndex); return(null); }; _LoadTableSetBodyAsync <Result <T1, T2> >(connectable, tableSetLoader, async, currentTableType); return(async); }
// reads first or next single table from multi-table datasource private static ResultSet <T> _Read <T>( IDataReader reader, Connectable connectable, Action <T> handler, ref int tableIndex, bool isFirstRead) { ResultSet <T> table = null; var isFirstOrHasNextTable = isFirstRead ? true : reader.NextResult(); if (isFirstOrHasNextTable) { if (handler == null) { if (typeof(T) == typeof(DataTable)) { table = new ResultSet <T>(LoadDataTable <T>(connectable, reader)); } else { table = new ResultSet <T>(_LoadTable <T>(connectable, reader)); } } else { _EnumerateTable <T>(connectable, reader, handler); } ++tableIndex; } else { throw Reader.NoMoreResultsetException <T>(connectable); } return(table); }
internal static Result LoadAll(Connectable connectable) { using (SqlConnection cn = new SqlConnection(connectable.ConnectionString)) { cn.Open(); Importer.ExecuteBulkInsert(connectable, cn); using (SqlCommand cmd = new SqlCommand(connectable.Sql, cn)) { cmd.CommandTimeout = connectable.CommandTimeout; SqlDataReader reader = cmd.ExecuteReader(); try { return(_LoadAll(connectable, reader)); } finally { reader.Close(); } } } }
private static void _EnumerateTable <T>(Connectable connectable, IDataReader reader, Action <T> rowHandler) { Type type = typeof(T); Func <IDataRecord, T> loader = null; if (!reader.Read()) { return; } if (reader.GetName(0) == Text.Reserved.ReturnValueColumnName) { throw new QueryTalkException("Reader._EnumerateTable<T>", QueryTalkExceptionType.NoMoreResultset, String.Format("table = {0}", type), Text.Method.Go); } QueryTalkException exception; loader = Loader.ProvideLoader <T>(reader, out exception); Loader.TryThrowException(exception, connectable); int rowix = 1; do { T row = loader(reader); Loader.SetRowAsLoaded(row); rowHandler(row); if (connectable.AsyncCanceled) { ThrowOperationCancelledByUserException <T>(connectable, rowix); } ++rowix; }while (reader.Read()); }
// asynchronously execute & load internal static Async <Result <T> > LoadTableAsync <T>(Connectable connectable, Action <T> rowHandler) { Type type = typeof(T); if (type == typeof(DataTable)) { throw new QueryTalkException("Reader.LoadTableAsync", QueryTalkExceptionType.DataTableCannotEnumerate, ((IName)connectable.Executable).Name, ".GoAsync<DataTable>", null); } var async = new Async <Result <T> >(connectable); async.Result = new Result <T>(connectable); int returnValue = 0; IEnumerable <T> table = null; // callback1: a method that is invoked when SQL processing has completed AsyncCallback onSqlRequestComplete = (iAsyncResult) => { Async asyncBegin = null; SqlDataReader reader = null; // async2: data loader processing reader asynchronously var loader = new Action <IDataReader>((readerLoader) => { try { table = _load <T>(connectable, reader, rowHandler); returnValue = Reader.ReadOutputData(readerLoader, connectable); async.Result = new Result <T>(connectable, table, returnValue); } catch (QueryTalkException ex) { async.SetResultException(ex); } catch (System.InvalidCastException) // "Specified cast is not valid." { var mismatchData = Loader.AnalyseInvalidCastException(connectable, type, 0); // throw exception with accurate report QueryTalkException exception; if (mismatchData != null) { exception = Reader.TypeMismatchException(((IName)connectable.Executable).Name, Text.Method.GoAsync, type, mismatchData); } // throw exception with less accurate report (not likely to happen) else { exception = Reader.TypeMismatchException( ((IName)connectable.Executable).Name, Text.Method.GoAsync, type, new Row <string, string, string>()); } async.SetResultException(exception); } catch (System.ArgumentNullException ex) { var exception = ClrException(ex, "Load", connectable, Text.Method.GoAsync, String.Format("data class = {0}", type)); async.SetResultException(exception); async.Exception.Extra = Text.Free.DataClassNoConstructorExtra; } catch (System.Exception ex) { async.SetClrException(ex, "LoadTableAsync.Loader", connectable, Text.Method.GoAsync); } finally { if (readerLoader != null) { readerLoader.Close(); } } }); try { asyncBegin = (Async)iAsyncResult.AsyncState; // Async object passed from BeginAsync method reader = async.Command.EndExecuteReader(iAsyncResult); // notifies main thread that SQL request has completed // ------------------------------------------------------------------------------------------- // here is a gap between two async calls: first is finished, the second is about to begin... // ------------------------------------------------------------------------------------------- // begin async2 async.AsyncResult2 = loader.BeginInvoke(reader, new AsyncCallback( new Action <IAsyncResult>((iAsyncResult2) => { try { loader.EndInvoke(iAsyncResult2); async.EndAsync(); } catch (System.Exception ex) { async.SetClrException(ex, "LoadTable.AsyncResult2", connectable, Text.Method.GoAsync); async.EndAsync(); } })), null); } catch (QueryTalkException ex) { async.SetResultException(ex); async.EndAsync(); } catch (System.Exception ex) { async.SetClrException(ex, "LoadTableAsync.OnSqlRequestComplete", connectable, Text.Method.GoAsync); async.EndAsync(); } }; async.BeginAsync(connectable, onSqlRequestComplete); return(async); }
private static int ReadOutputData(IDataReader reader, Connectable connectable) { object output; int returnValue = 0; try { bool found = false; do { while (reader.Read()) { if (reader.GetName(0) == Text.Reserved.ReturnValueColumnName) { found = true; break; // last datasource table always exists } } } while (!found && reader.NextResult()); if (found) { int count = reader.FieldCount; var outputArguments = ParameterArgument.GetOutputArguments(connectable.Executable.Arguments); for (int i = 0; i < count; ++i) { if (reader.IsDBNull(i)) { output = null; } else { output = reader.GetValue(i); } // output values: if (i >= 1) { outputArguments[i - 1].SetOutput(output); } // return value: else { if (output != null && output.GetType() == typeof(System.Int32)) { int.TryParse(output.ToString(), out returnValue); connectable.ReturnValue = returnValue; } } } connectable.OutputArguments = outputArguments; } return(returnValue); } catch (System.Exception ex) { throw ClrException(ex, "ReaderOutputData", connectable, null); } }
// The only purpose of this method is to give the client more accurate information about the target property // which caused the InvalidCastException exception. This method may even fail with inner exception and/or return null, // and in that case the less accurate InvalidCastException info will be shown to the client. internal static Row <string, string, string> AnalyseInvalidCastException(Connectable connectable, Type type, int tableIndex) { try { using (SqlConnection cn = new SqlConnection(connectable.ConnectionString)) { cn.Open(); Importer.ExecuteBulkInsert(connectable, cn); using (SqlCommand cmd = new SqlCommand(connectable.Sql, cn)) { cmd.CommandTimeout = connectable.CommandTimeout; int i = 0; using (SqlDataReader reader = cmd.ExecuteReader()) { while (i++ != tableIndex) { if (!reader.NextResult()) { return(null); } } DataTable schema = reader.GetSchemaTable(); int hash = GetLoaderHash(reader); var cacheKey = Cache.CreateLoaderCacheKey(hash, type); Cache.LoaderCacheValue cacheValue; if (!Cache.Loaders.TryGetValue(cacheKey, out cacheValue)) { return(null); // do not continue with analysis if cache does not exist (not likely) } int j = 0; foreach (var column in cacheValue.Columns) { DataRow row; if (Row.IsRow(type)) { row = schema.Rows[j++]; } else { row = schema.AsEnumerable() .Where(a => a.Field <string>(_columnNameText).EqualsCS(column.ColumnName)) .Select(a => a) .FirstOrDefault(); } if (row != null) { string sqlTypeName = row.Field <string>(_dataTypeNameText); var clrInfo = Mapping.ClrMapping[column.ValueType]; bool ismatch = false; foreach (var dbtype in clrInfo.DTypes) { if (Mapping.SqlMapping[dbtype].SqlPlain.EqualsCS(sqlTypeName, false)) { ismatch = true; break; } } if (!ismatch) { return(Row.Create(column.ColumnName, column.ValueType.ToString(), sqlTypeName)); } } } } } } } // safe: the "real" exception has already been caught catch { } return(null); }
// asynchronously execute & load internal static Async <Result <T> > LoadDataTableAsync <T>(Connectable connectable) { var async = new Async <Result <T> >(connectable); async.Result = new Result <T>(connectable); int returnValue = 0; DataTable table = null; // callback1: a method that is invoked when SQL processing has completed AsyncCallback onSqlRequestComplete = (iAsyncResult) => { Async asyncBegin = null; SqlDataReader reader = null; // async2: data loader processing reader asynchronously var loader = new Action <IDataReader>((readerLoader) => { try { table = LoadDataTable <T>(connectable, readerLoader); returnValue = Reader.ReadOutputData(readerLoader, connectable); async.Result = new Result <T>(connectable, table, returnValue); } catch (QueryTalkException ex) { if (async.SetResultException(ex)) { async.Exception.Method = Text.Method.GoAsync; } } catch (System.Exception ex) { async.SetClrException(ex, "LoadDataTableAsync.Loader", connectable, Text.Method.GoAsync); } finally { if (readerLoader != null) { readerLoader.Close(); } } }); try { asyncBegin = (Async)iAsyncResult.AsyncState; reader = async.Command.EndExecuteReader(iAsyncResult); // ------------------------------------------------------------------------------------------- // here is a gap between two async calls: first is finished, the second is about to begin... // ------------------------------------------------------------------------------------------- async.AsyncResult2 = loader.BeginInvoke(reader, new AsyncCallback( new Action <IAsyncResult>((iAsyncResult2) => { try { loader.EndInvoke(iAsyncResult2); async.EndAsync(); } catch (System.Exception ex) { async.SetClrException(ex, "LoadDataTable.AsyncResult2", connectable, Text.Method.GoAsync); async.EndAsync(); } })), null); } catch (QueryTalkException ex) { async.SetResultException(ex); async.EndAsync(); } catch (System.Exception ex) { async.SetClrException(ex, "LoadDataTableAsync<T>.OnSqlRequestComplete", connectable, Text.Method.GoAsync); async.EndAsync(); } }; async.BeginAsync(connectable, onSqlRequestComplete); return(async); }
internal static Result <T> LoadTable <T>(Connectable connectable, Action <T> rowHandler, bool allowEmpty = false) { IEnumerable <T> table = null; int returnValue = 0; Type type = typeof(T); if (type == typeof(DataTable)) { throw new QueryTalkException("Reader.LoadTable<T>", QueryTalkExceptionType.DataTableCannotEnumerate, ((IName)connectable.Executable).Name, ".Go<DataTable>", null); } try { using (SqlConnection cn = new SqlConnection(connectable.ConnectionString)) { cn.Open(); Importer.ExecuteBulkInsert(connectable, cn); using (SqlCommand cmd = new SqlCommand(connectable.Sql, cn)) { cmd.CommandTimeout = connectable.CommandTimeout; SqlDataReader reader = cmd.ExecuteReader(); try { table = _load <T>(connectable, reader, rowHandler, allowEmpty); returnValue = Reader.ReadOutputData(reader, connectable); } finally { reader.Close(); } } } } catch (QueryTalkException ex) { ex.ObjectName = ((IName)connectable.Executable).Name; ex.Method = Text.Method.Go; throw; } catch (System.InvalidCastException) // "Specified cast is not valid." { var mismatchData = Loader.AnalyseInvalidCastException(connectable, type, 0); // throw exception with accurate report if (mismatchData != null) { var exception = Reader.TypeMismatchException(((IName)connectable.Executable).Name, Text.Method.Go, type, mismatchData); throw exception; } // throw exception with less accurate report (not likely to happen) else { var exception = Reader.TypeMismatchException( ((IName)connectable.Executable).Name, Text.Method.Go, type, new Row <string, string, string>()); throw exception; } } catch (System.ArgumentNullException ex) { var exception = ClrException(ex, "Load", connectable, Text.Method.Go, String.Format("data class = {0}", typeof(T))); exception.Extra = Text.Free.DataClassNoConstructorExtra; throw exception; } var result = new Result <T>(connectable, table); result.ReturnValue = returnValue; return(result); }
internal TestingForm(Connectable connectable, TestingOption option, string title) { try { _connectable = connectable; // store connectable object which may be used after the testing, for the execution _body = connectable.Executable.Body; // store body InitializeComponent(); _offToolTip = new ToolTip(); _offToolTip.SetToolTip(_off, "Close and set Testing Environment OFF."); _interruptToolTip = new ToolTip(); _interruptToolTip.SetToolTip(_interrupt, "Interrupt the execution of the Testing Environment"); _params = new Dictionary <string, TVP>(); this.ShowIcon = false; Text = String.Format("{0} | {1}", Wall.Text.Free.QtTesting, ParseConnString()); _statusRows.Text = null; var name = ((IName)_connectable).Name; if (title != null) { _name.Text = title; _statusName.Text = title; } else if (name != null) { _name.Text = name; _statusName.Text = (name == Wall.Text.NotAvailable) ? null : name; } else { _name.Text = Wall.Text.NotAvailable; _statusName.Text = null; } _sql.Text = _connectable.Body; _tranCodeInfo = new TransactionCodeInfo(_connectable.Body); // if compilable object is a stored procedure, show extra message if (_connectable.Executable.Compilable.CompilableType == Compilable.ObjectType.StoredProc) { ShowMessage(Wall.Text.Free.StoredProcTestMessage); } _sqlContextMenu = new ContextMenuStrip(); ToolStripMenuItem menuItem = new ToolStripMenuItem(Wall.Text.Free.RestoreSQL, Properties.Resources.restore, (o, e) => { _sql.ThreadSafeInvoke(new Action(() => _sql.Text = _body)); }); _sqlContextMenu.Items.Add(menuItem); _sql.ContextMenuStrip = _sqlContextMenu; AddEventHandlers(); ShowParameterGrid(); // clear loader cache // note: // We clear cache in order to remove all mapped loaders that contain graph objects (associations) // that cannot be shown in the grid. Otherwise the grid does not show the correct data. Cache.Loaders.Clear(); this.Load += (o, e) => { try { if (option == TestingOption.OpenAndExecute) { Run(); } } catch (Exception ex) { ShowException(ex); } }; } catch (System.Exception ex) { throw ClrException(ex); } }
private static void _LoadTableSetBody( Connectable connectable, Func <IDataReader, TableSetLoaderArgs> tableSetLoader, Type currentTableType, out int returnValue) { int tableIndex = 0; try { using (SqlConnection cn = new SqlConnection(connectable.ConnectionString)) { cn.Open(); Importer.ExecuteBulkInsert(connectable, cn); using (SqlCommand cmd = new SqlCommand(connectable.Sql, cn)) { cmd.CommandTimeout = connectable.CommandTimeout; SqlDataReader reader = cmd.ExecuteReader(); try { var loaderException = tableSetLoader(reader); if (loaderException != null) { currentTableType = loaderException.TableType; tableIndex = loaderException.TableIndex; throw loaderException.Exception; } returnValue = Reader.ReadOutputData(reader, connectable); } finally { reader.Close(); } } } } catch (QueryTalkException ex) { ex.ObjectName = ((IName)connectable.Executable).Name; ex.Method = Text.Method.Go; throw; } catch (System.InvalidCastException) // "Specified cast is not valid." { var mismatchData = Loader.AnalyseInvalidCastException(connectable, currentTableType, tableIndex); // throw exception with more accurate report if (mismatchData != null) { throw Reader.TypeMismatchException( ((IName)connectable.Executable).Name, Text.Method.Go, currentTableType, mismatchData, tableIndex); } // throw exception with less accurate report (not likely to happen) else { throw Reader.TypeMismatchException( ((IName)connectable.Executable).Name, Text.Method.Go, currentTableType, new Row <string, string, string>(), tableIndex); } } }
private static void _LoadTableSetBodyAsync <T>( Connectable connectable, Func <IDataReader, TableSetLoaderArgs> tableSetLoader, // main loader delegate method Async <T> async, Type currentTableType) { int loaderReturnValue = 0; int tableIndex = 0; // callback1: a method that is invoked when SQL processing has completed AsyncCallback onSqlRequestComplete = (iAsyncResult) => { Async asyncBegin = null; SqlDataReader reader = null; // async2: data loader processing reader asynchronously var loader = new Action <IDataReader>((readerLoader) => { try { var loaderException = tableSetLoader(reader); if (loaderException != null) { currentTableType = loaderException.TableType; tableIndex = loaderException.TableIndex; throw loaderException.Exception; } // load return value loaderReturnValue = Reader.ReadOutputData(reader, connectable); ((dynamic)async.Result).ReturnValue = loaderReturnValue; } catch (QueryTalkException ex) { if (async.SetResultException(ex)) { async.Exception.ObjectName = ((IName)connectable.Executable).Name; async.Exception.Method = Text.Method.GoAsync; } } catch (System.InvalidCastException) // "Specified cast is not valid." { var mismatchData = Loader.AnalyseInvalidCastException(connectable, currentTableType, tableIndex); // throw exception with accurate report if (mismatchData != null) { throw Reader.TypeMismatchException( ((IName)connectable.Executable).Name, Text.Method.GoAsync, currentTableType, mismatchData, tableIndex); } // throw exception with less accurate report (not likely to happen) else { throw Reader.TypeMismatchException( ((IName)connectable.Executable).Name, Text.Method.GoAsync, currentTableType, new Row <string, string, string>(), tableIndex); } } catch (System.Exception ex) { QueryTalkException exception = new QueryTalkException("Reader._LoadTableSetBodyAsync.Loader", QueryTalkExceptionType.ClrException, ((IName)connectable.Executable).Name, Text.Method.GoAsync, String.Format("table = {0}", currentTableType)); exception.ClrException = ex; async.SetResultException(exception); } finally { if (readerLoader != null) { readerLoader.Close(); } } }); try { asyncBegin = (Async)iAsyncResult.AsyncState; reader = async.Command.EndExecuteReader(iAsyncResult); // ------------------------------------------------------------------------------------------- // here is a gap between two async calls: first is finished, the second is about to begin... // ------------------------------------------------------------------------------------------- async.AsyncResult2 = loader.BeginInvoke(reader, new AsyncCallback( new Action <IAsyncResult>((iAsyncResult2) => { try { loader.EndInvoke(iAsyncResult2); async.EndAsync(); } catch (QueryTalkException ex) { ex.Method = Text.Method.GoAsync; async.SetResultException(ex); async.EndAsync(); } catch (System.Exception ex) { async.SetClrException(ex, "LoadTableSet.AsyncResult2", connectable, Text.Method.GoAsync); async.EndAsync(); } })), null); } catch (QueryTalkException ex) { ex.ObjectName = ((IName)connectable.Executable).Name; ex.Method = Text.Method.GoAsync; async.SetResultException(ex); async.EndAsync(); } catch (System.InvalidCastException) // "Specified cast is not valid." { var mismatchData = Loader.AnalyseInvalidCastException(connectable, currentTableType, tableIndex); // throw exception with accurate report QueryTalkException exception; if (mismatchData != null) { exception = Reader.TypeMismatchException( ((IName)connectable.Executable).Name, Text.Method.GoAsync, currentTableType, mismatchData); } // throw exception with less accurate report (not likely to happen) else { exception = Reader.TypeMismatchException( ((IName)connectable.Executable).Name, Text.Method.GoAsync, currentTableType, new Row <string, string, string>()); } async.SetResultException(exception); async.EndAsync(); } catch (System.Exception ex) { QueryTalkException exception = new QueryTalkException("Reader._LoadTableSetBodyAsync.OnSqlRequestComplete", QueryTalkExceptionType.ClrException, ((IName)connectable.Executable).Name, Text.Method.GoAsync, String.Format("table = {0}", currentTableType)); exception.ClrException = ex; async.SetResultException(exception); async.EndAsync(); } }; async.BeginAsync(connectable, onSqlRequestComplete); }
private static Result _LoadAll(Connectable connectable, SqlDataReader reader) { Result result = null; int tableIndex = 0; Type resultType = typeof(Result); try { do { if (reader.GetName(0) == Text.Reserved.ReturnValueColumnName) { if (result == null) { result = new Result(connectable); } result.TableCount = tableIndex; result.ReturnValue = Reader.ReadOutputDataOnFound(reader, connectable); if (reader.NextResult()) { Reader.ThrowQueryTalkReservedNameException(); } return(result); // the code is supposed to always exit the method here } var table = _LoadTable <dynamic>(connectable, reader); string tableName = String.Format("{0}{1}", Text.Free.Table, tableIndex + 1); // Table1 if (tableIndex == 0) { result = new Result(connectable, table); } // Table2.. else { var ptable = new ResultSet <dynamic>(table); // Table2..Table9 if (tableIndex < 9) { resultType.GetProperty(tableName).SetValue(result, ptable, null); } // Table10.. else { if (result.OtherTables == null) { result.OtherTables = new ExpandoObject(); } ((IDictionary <string, object>)result.OtherTables)[tableName] = ptable; } } ++tableIndex; }while (reader.NextResult()); } catch (System.InvalidCastException) // "Specified cast is not valid." { var mismatchData = Loader.AnalyseInvalidCastException(connectable, typeof(object), tableIndex); // throw exception with more accurate report if (mismatchData != null) { var exception = Reader.TypeMismatchException(((IName)connectable.Executable).Name, Text.Method.Go, typeof(object), mismatchData); throw exception; } // throw exception with less accurate report (not likely to happen) else { var exception = Reader.TypeMismatchException( ((IName)connectable.Executable).Name, Text.Method.Go, typeof(object), new Row <string, string, string>()); throw exception; } } return(result); // the code is not supposed to ever reach this line }
// isSilent: // if true, then this method is used by other CRUD method (.UpdateGo/.InsertGo) which requires special treatment. internal static Result <T> ReloadGo <T>(Assembly client, DbRow row, bool forceMirroring, ConnectBy connectBy, bool isSilent = false) where T : DbRow { var name = Text.NotAvailable; try { ColumnSelector selector = forceMirroring ? ColumnSelector.All : ColumnSelector.RK; if (isSilent) { selector = ColumnSelector.RK; } if (row == null) { throw new QueryTalkException("Crud.GoReload", QueryTalkExceptionType.ArgumentNull, "row = null", Text.Method.ReloadGo); } Crud.CheckTable(row, Text.Method.ReloadGo); List <ParameterArgument> args = new List <ParameterArgument>(); var map = DbMapping.TryGetNodeMap(row); name = map.Name.Sql; if (forceMirroring) { if (!row.GetStatus().IsUpdatable()) { var arguments = map.BuildExceptionReport(row.GetOriginalRKValues(), row.GetOriginalRowversionValue()); throw new QueryTalkException("Crud.ReloadGo", QueryTalkExceptionType.InvalidMirroring, arguments, Text.Method.ReloadGo).SetObjectName(map.Name.Sql); } } object[] originalValues; if (selector == ColumnSelector.All) { if (map.HasRowversion) { originalValues = new object[] { row.GetOriginalRowversionValue() }; } else { originalValues = row.GetOriginalValues(); } } // RK selector else { originalValues = row.GetOriginalRKValues(); } for (int i = 0; i < originalValues.Length; ++i) { args.Add(new ParameterArgument(new Value(originalValues[i]))); } args.Add(map.Name); if (selector == ColumnSelector.All) { args.Add(new ParameterArgument(map.BuildOptimisticPredicate(originalValues, 1))); } else { args.Add(new ParameterArgument(map.BuildRKPredicate(originalValues, 1))); } var cpass = ReloadProc(row.NodeID, selector).Pass(args.ToArray()); cpass.SetRootMap(row.NodeID); // important! Connectable connectable = Reader.GetConnectable(client, row, cpass, connectBy); var result = connectable.Go <T>(); // success if (result.RowCount > 0) { PropertyAccessor.SetValues(row, result.First().GetOriginalValues()); row.SetStatus(DbRowStatus.Loaded); return(new Result <T>(true, 0)); } // not found else { var arguments = map.BuildExceptionReport(row.GetOriginalRKValues(), row.GetOriginalRowversionValue()); if (!isSilent) { if (forceMirroring) { throw new QueryTalkException("Crud.ReloadGo", QueryTalkExceptionType.ConcurrencyViolation, arguments, Text.Method.ReloadGo).SetObjectName(map.Name.Sql); } else { throw new QueryTalkException("Crud.ReloadGo", QueryTalkExceptionType.ReloadFailed, arguments, Text.Method.ReloadGo).SetObjectName(map.Name.Sql); } } else { row.SetStatus(DbRowStatus.Faulted); return(new Result <T>(true, 0)); } } } catch (QueryTalkException ex) { Loader.TryThrowInvalidSqlOperationException(ex, name, Text.Method.ReloadGo); throw; } catch (System.Exception ex) { var ex2 = Crud.ClrException(ex, name, Text.Method.ReloadGo); Loader.TryThrowInvalidSqlOperationException(ex2, name); throw ex2; } }