public override EtlStepResult Invoke(EtlContext context, IEtlLogger logger)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            if (this.Source == null)
            {
                throw new InvalidOperationException("Source cannot be null");
            }

            if (string.IsNullOrEmpty(this.Source.ConnectionString))
            {
                throw new InvalidOperationException("Source.ConnectionString cannot be empty");
            }

            if (string.IsNullOrEmpty(this.Source.ProviderName))
            {
                throw new InvalidOperationException("Source.ProviderName cannot be empty");
            }

            if (string.IsNullOrEmpty(this.Source.Text))
            {
                throw new InvalidOperationException("Source.Text cannot be empty");
            }

            var result = new EtlStepResult(EtlStatus.Succeeded, null);

            var rowCounter = (this.Counters != null && this.Counters.RowCount != null && !string.IsNullOrEmpty(this.Counters.RowCount.CounterName))
                ? new EtlCounter
                {
                    EtlPackageId = context.EtlPackageId,
                    EtlSessionId = context.EtlSessionId,
                    EntityName = this.Counters.RowCount.EntityName,
                    CounterName = this.Counters.RowCount.CounterName,
                }
                : null;

            var hasOutputVariables = this.OutputVariables != null && this.OutputVariables.FirstRow.Count > 0;
            var hasRowCounter = rowCounter != null;

            using (var dbAccessor = new DBAccessor(this.Source.ConnectionString, this.Source.ProviderName))
            {
                if (hasOutputVariables || hasRowCounter)
                {
                    using (var dbReader = dbAccessor.ExecuteQuery(this.Source.Text, EtlQueryParameter.ToDictionary(this.Source.Parameters), this.TimeoutMilliseconds))
                    {
                        if (dbReader.Read())
                        {
                            if (hasRowCounter)
                            {
                                rowCounter.CounterValue++;
                            }

                            if (hasOutputVariables)
                            {
                                foreach (var firstRowResult in this.OutputVariables.FirstRow)
                                {
                                    var firstRowResultValue = EtlValueTranslation.Evaluate(firstRowResult.SourceFieldName, firstRowResult.SourceFieldTranslation, dbReader, firstRowResult.DefaultValue);
                                    result.VariableAssignments.Add(new EtlVariableAssignment(firstRowResult.VariableName, EtlValueConverter.ToString(firstRowResultValue)));
                                }
                            }
                        }

                        if (hasRowCounter)
                        {
                            while (dbReader.Read())
                            {
                                rowCounter.CounterValue++;
                            }

                            rowCounter.DateTime = DateTime.Now;
                            rowCounter.UtcDateTime = rowCounter.DateTime.ToUniversalTime();
                            logger.LogEtlCounter(rowCounter);
                        }
                    }
                }
                else
                {
                    dbAccessor.ExecuteNonQuery(this.Source.Text, EtlQueryParameter.ToDictionary(this.Source.Parameters), this.TimeoutMilliseconds);
                }
            }

            return result;
        }
        public override EtlStepResult Invoke(EtlContext context, IEtlLogger logger)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            if (this.Source == null)
            {
                throw new InvalidOperationException("Source cannot be null");
            }

            if (this.Destination == null)
            {
                throw new InvalidOperationException("Destination cannot be null");
            }

            if (string.IsNullOrEmpty(this.Source.ConnectionString))
            {
                throw new InvalidOperationException("Source.ConnectionString cannot be empty");
            }

            if (string.IsNullOrEmpty(this.Source.ProviderName))
            {
                throw new InvalidOperationException("Source.ProviderName cannot be empty");
            }

            if (string.IsNullOrEmpty(this.Source.Text))
            {
                throw new InvalidOperationException("Source.Text cannot be empty");
            }

            if (string.IsNullOrEmpty(this.Destination.ConnectionString))
            {
                throw new InvalidOperationException("Destination.ConnectionString cannot be empty");
            }

            if (string.IsNullOrEmpty(this.Destination.ProviderName))
            {
                throw new InvalidOperationException("Destination.ProviderName cannot be empty");
            }

            if (string.IsNullOrEmpty(this.Destination.TableName))
            {
                throw new InvalidOperationException("Destination.TableName cannot be empty");
            }

            if (this.Mappings.Count == 0)
            {
                throw new InvalidOperationException("Mappings not specified");
            }

            var result = new EtlStepResult(EtlStatus.Succeeded, null);

            var sourceRowCount = 0L;
            var insertedRowCount = 0L;
            var errorRowCount = 0L;

            using (var dbAccessor = new DBAccessor(this.Source.ConnectionString, this.Source.ProviderName))
            {
                using (var dbReader = dbAccessor.ExecuteQuery(this.Source.Text, EtlQueryParameter.ToDictionary(this.Source.Parameters), this.TimeoutMilliseconds))
                {
                    using (var mapReader = new EtlMappedDataReader(dbReader, this.Mappings))
                    {
                        var dbWriter = new DBTableWriter(this.Destination.ConnectionString, this.Destination.ProviderName, this.Destination.TableName);
                        dbWriter.ErrorOccured += delegate(object sender, DBTableWriterErrorEventArgs e)
                        {
                            var errorDateTime = DateTime.Now;
                            result.Status = EtlStatus.FinishedWithLosses;
                            result.Message = e.Message;

                            errorRowCount++;

                            logger.LogEtlMessage
                            (
                                new EtlMessage
                                {
                                    EtlPackageId = context.EtlPackageId,
                                    EtlSessionId = context.EtlSessionId,
                                    EtlStepName = this.Name,
                                    LogDateTime = errorDateTime,
                                    LogUtcDateTime = errorDateTime.ToUniversalTime(),
                                    MessageType = EtlMessageType.Error,
                                    Text = e.Message,
                                    Flags = e.RecordIndex,
                                    StackTrace = e.Exception != null ? e.Exception.StackTrace : null,
                                }
                            );

                            if (this.DataLossBehavior == EtlImportDataLossBehavior.Skip)
                            {
                                result.Status = EtlStatus.FinishedWithLosses;
                                e.TrySkipError = true;
                            }
                            else
                            {
                                result.Status = EtlStatus.Failed;
                            }
                        };

                        insertedRowCount = dbWriter.Write(mapReader, this.TimeoutMilliseconds, this.BatchSize);
                    }
                }
            }

            sourceRowCount = insertedRowCount + errorRowCount;

            //logger.LogEtlMessage(new EtlMessage
            //{
            //    EtlPackageId = context.EtlPackageId,
            //    EtlSessionId = context.EtlSessionId,
            //    EtlStepId = this.Id,
            //    LogDateTime = endDateTime,
            //    LogUtcDateTime = endDateTime.ToUniversalTime(),
            //    MessageType = EtlMessageType.Statistics,
            //    Text = "Found",
            //    Flags = sourceRowCount,
            //});

            //logger.LogEtlMessage(new EtlMessage
            //{
            //    EtlPackageId = context.EtlPackageId,
            //    EtlSessionId = context.EtlSessionId,
            //    EtlStepId = this.Id,
            //    LogDateTime = endDateTime,
            //    LogUtcDateTime = endDateTime.ToUniversalTime(),
            //    MessageType = EtlMessageType.Statistics,
            //    Text = "Errors",
            //    Flags = errorRowCount,
            //});

            //logger.LogEtlMessage(new EtlMessage
            //{
            //    EtlPackageId = context.EtlPackageId,
            //    EtlSessionId = context.EtlSessionId,
            //    EtlStepId = this.Id,
            //    LogDateTime = endDateTime,
            //    LogUtcDateTime = endDateTime.ToUniversalTime(),
            //    MessageType = EtlMessageType.Statistics,
            //    Text = "Inserted",
            //    Flags = insertedRowCount,
            //});

            return result;
        }
        public override EtlStepResult Invoke(EtlContext context, IEtlLogger logger)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            if (this.Source == null)
            {
                throw new InvalidOperationException("Source cannot be null");
            }

            if (string.IsNullOrEmpty(this.Source.ConnectionString))
            {
                throw new InvalidOperationException("ConnectionString cannot be empty");
            }

            if (string.IsNullOrEmpty(this.Source.ProviderName))
            {
                throw new InvalidOperationException("ProviderName cannot be empty");
            }

            if (string.IsNullOrEmpty(this.Source.ProcedureName))
            {
                throw new InvalidOperationException("ProcedureName cannot be empty");
            }

            var result = new EtlStepResult(EtlStatus.Succeeded, null);
            var hasOutputVariables = this.OutputVariables != null && this.OutputVariables.FirstRow.Count > 0;

            using (var dbAccessor = new DBAccessor(this.Source.ConnectionString, this.Source.ProviderName))
            {
                if (hasOutputVariables)
                {
                    using (var dbReader = dbAccessor.ExecuteProcedureReader(this.Source.ProcedureName, EtlProcedureParameter.ToDictionary(this.Source.Parameters), this.TimeoutMilliseconds))
                    {
                        if (dbReader.Read())
                        {
                            foreach (var firstRowResult in this.OutputVariables.FirstRow)
                            {
                                var firstRowResultValue = EtlValueTranslation.Evaluate(firstRowResult.SourceFieldName, firstRowResult.SourceFieldTranslation, dbReader, firstRowResult.DefaultValue);
                                result.VariableAssignments.Add(new EtlVariableAssignment(firstRowResult.VariableName, EtlValueConverter.ToString(firstRowResultValue)));
                            }
                        }
                    }
                }
                else
                {
                    dbAccessor.ExecuteProcedure(this.Source.ProcedureName, EtlProcedureParameter.ToDictionary(this.Source.Parameters), this.TimeoutMilliseconds);
                }
            }

            return result;
        }
        public override EtlStepResult Invoke(EtlContext context, IEtlLogger logger)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            if (this.Source == null)
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.PropertyCannotBeNull, "Source"));
            }

            if (this.Destination == null)
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.PropertyCannotBeNull, "Destination"));
            }

            if (string.IsNullOrEmpty(this.Source.ConnectionString))
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.PropertyCannotBeNull, "Destination.ConnectionString"));
            }

            if (string.IsNullOrEmpty(this.Source.ProviderName))
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.PropertyCannotBeNull, "Source.ProviderName"));
            }

            if (string.IsNullOrEmpty(this.Source.Text))
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.PropertyCannotBeNull, "Source.Text"));
            }

            if (string.IsNullOrEmpty(this.Destination.FieldDelimiter))
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.PropertyCannotBeNull, "Destination.FieldDelimiter"));
            }

            if (string.IsNullOrEmpty(this.Destination.FilePath))
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.PropertyCannotBeNull, "Destination.FilePath"));
            }

            if (this.Destination.FieldDelimiter.Length != 1)
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.PropertyTooLong, "Destination.FieldDelimiter", 1));
            }

            if (this.Destination.Quote != null && this.Destination.Quote.Length != 1)
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.PropertyTooLong, "Destination.Quote", 1));
            }

            if (this.Destination.Escape != null && this.Destination.Escape.Length != 1)
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.PropertyTooLong, "Destination.Escape", 1));
            }

            if (this.Destination != null)
            {
                var destinationFolderPath = Path.GetDirectoryName(this.Destination.FilePath);

                if (!string.IsNullOrEmpty(destinationFolderPath))
                {
                    if (!Directory.Exists(destinationFolderPath))
                    {
                        Directory.CreateDirectory(destinationFolderPath);
                    }
                }
            }

            //if (this.Mappings.Count == 0)
            //{
            //    throw new InvalidOperationException("Mappings not specified");
            //}

            var result = new EtlStepResult(EtlStatus.Succeeded, null);

            var sourceRowCount = 0L;
            var writtenRowCount = 0L;

            var encoding = Encoding.GetEncoding(this.Destination.CodePage);
            var csvSyntax = new CsvSyntaxInfo
            {
                HasHeaders = this.Destination.HasHeaders,
                FieldDelimiter = this.Destination.FieldDelimiter[0],
                Quote = this.Destination.Quote != null ? this.Destination.Quote[0] : DefaultQuote,
                Escape = this.Destination.Escape != null ? this.Destination.Escape[0] : DefaultEscape,
                LineDelimiter1 = this.Destination.LineDelimiter != null ? this.Destination.LineDelimiter[0] : DefaultLineDelimiter[0],
                LineDelimiter2 = this.Destination.LineDelimiter != null ? this.Destination.LineDelimiter[1] : DefaultLineDelimiter[1],
            };

            using (var dbAccessor = new DBAccessor(this.Source.ConnectionString, this.Source.ProviderName))
            {
                using (var dbReader = dbAccessor.ExecuteQuery(this.Source.Text, EtlQueryParameter.ToDictionary(this.Source.Parameters), this.TimeoutMilliseconds))
                {
                    using (var mapReader = new EtlMappedDataReader(dbReader, this.Mappings))
                    {
                        using (var fileWriter = new StreamWriter(this.Destination.FilePath, false, encoding))
                        {
                            var csvWriter = new CsvWriter(fileWriter, csvSyntax);

                            writtenRowCount = csvWriter.Write(mapReader);
                            sourceRowCount = writtenRowCount;
                        }
                    }
                }
            }

            //logger.LogEtlMessage(new EtlMessage
            //{
            //    EtlPackageId = context.EtlPackageId,
            //    EtlSessionId = context.EtlSessionId,
            //    EtlStepId = this.Id,
            //    LogDateTime = endDateTime,
            //    LogUtcDateTime = endDateTime.ToUniversalTime(),
            //    MessageType = EtlMessageType.Statistics,
            //    Text = "Found",
            //    Flags = sourceRowCount,
            //});

            //logger.LogEtlMessage(new EtlMessage
            //{
            //    EtlPackageId = context.EtlPackageId,
            //    EtlSessionId = context.EtlSessionId,
            //    EtlStepId = this.Id,
            //    LogDateTime = endDateTime,
            //    LogUtcDateTime = endDateTime.ToUniversalTime(),
            //    MessageType = EtlMessageType.Statistics,
            //    Text = "Exported",
            //    Flags = writtenRowCount,
            //});

            return result;
        }