Beispiel #1
0
        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);
                    }
                });
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
 private static ResultSet <T> ReadFirstOrNextTable <T>(
     IDataReader reader,
     Connectable connectable,
     ref int tableIndex
     )
 {
     return(_Read <T>(reader, connectable, null, ref tableIndex, tableIndex == 0));
 }
Beispiel #7
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;
     }
 }
Beispiel #8
0
 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))));
 }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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);
            }
        }
Beispiel #12
0
 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));
 }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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));
        }
Beispiel #16
0
        // 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);
            }
        }
Beispiel #17
0
        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);
        }
Beispiel #18
0
        // 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);
        }
Beispiel #19
0
        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();
                    }
                }
            }
        }
Beispiel #20
0
        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());
        }
Beispiel #21
0
        // 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);
        }
Beispiel #22
0
        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);
            }
        }
Beispiel #23
0
        // 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);
        }
Beispiel #24
0
        // 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);
        }
Beispiel #25
0
        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);
        }
Beispiel #26
0
        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);
            }
        }
Beispiel #27
0
        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);
                }
            }
        }
Beispiel #28
0
        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);
        }
Beispiel #29
0
        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
        }
Beispiel #30
0
        // 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;
            }
        }