private void HandleColumnErrorDistribution(DTSRowDisposition rowDisposition, string columnIdString, string columnData, string rowData, Exception ex) { bool rowHandled = false; string errorMessage = MessageStrings.FailedToAssignColumnValue(this.currentRowCount, columnData, columnIdString); if (this.bufferService.ErrorOutputUsed) { if (rowDisposition == DTSRowDisposition.RD_RedirectRow) { this.bufferService.AddErrorRow(errorMessage, columnData, rowData); rowHandled = true; } else if (rowDisposition == DTSRowDisposition.RD_IgnoreFailure) { rowHandled = true; } } this.bufferService.RemoveRow(); if (!rowHandled) { throw new BufferSinkException(errorMessage, ex); } }
// //You can use the following additional attributes as you write your tests: // //Use ClassInitialize to run code before running the first test in the class //[ClassInitialize()] //public static void MyClassInitialize(TestContext testContext) //{ //} // //Use ClassCleanup to run code after all tests in a class have run //[ClassCleanup()] //public static void MyClassCleanup() //{ //} // //Use TestInitialize to run code before running each test //[TestInitialize()] //public void MyTestInitialize() //{ //} // //Use TestCleanup to run code after each test has run //[TestCleanup()] //public void MyTestCleanup() //{ //} // #endregion private void GenerateOutputColumns(string[] columnNames, bool errorBufferUsed, DTSRowDisposition errorDisposition, DTSRowDisposition truncationDisposition, out OutputTestImpl output, out ComponentBufferServiceTestImpl bufferService) { output = new OutputTestImpl(); bufferService = new ComponentBufferServiceTestImpl(columnNames, errorBufferUsed); int currentID = 1; foreach (string columnName in columnNames) { IDTSOutputColumn100 outputColumn = output.OutputColumnCollection.New(); outputColumn.ID = currentID; outputColumn.Name = columnName; outputColumn.ErrorRowDisposition = errorDisposition; outputColumn.TruncationRowDisposition = truncationDisposition; currentID++; } }
/// <summary> /// Will perform the user-specified behaviour when a processing error occurs /// </summary> /// <param name="disposition">How the error should be handled</param> /// <param name="defaultBuffer">The default output buffer</param> /// <param name="errorBuffer">The error output buffer</param> /// <param name="failingColumnInfo">The information for the problematic column</param> /// <param name="ex">The exception caught from processing (optional)</param> private void HandleProcessingError(DTSRowDisposition disposition, PipelineBuffer defaultBuffer, PipelineBuffer errorBuffer, ColumnInfo failingColumnInfo, Exception ex) { switch (disposition) { case DTSRowDisposition.RD_RedirectRow: if (errorBuffer == null) { throw new InvalidOperationException("There must be an error output defined if redirection was specified"); } // Add a row to the error buffer. errorBuffer.AddRow(); // Get the values from the default buffer // and copy them to the error buffer. var errorOutputColumns = GetErrorOutputColumns().ToArray(); foreach (IDTSOutputColumn100 column in errorOutputColumns) { ColumnInfo copiedColumnInfo = GetColumnInfo(column.Name); if (copiedColumnInfo != null) { errorBuffer[copiedColumnInfo.ErrorOuputBufferColumnIndex] = defaultBuffer[copiedColumnInfo.OuputBufferColumnIndex]; } } // Set the error information. int errorCode = (ex == null ? 0 : System.Runtime.InteropServices.Marshal.GetHRForException(ex)); errorBuffer.SetErrorInfo(errorOutputID, errorCode, failingColumnInfo.OutputColumn.LineageID); // Remove the row that was added to the default buffer. defaultBuffer.RemoveRow(); break; case DTSRowDisposition.RD_FailComponent: throw new Exception(String.Format("There was an issue with column: {0}", failingColumnInfo.OutputColumn.Name), ex); } }
/// <summary> /// Will perform the user-specified behaviour when a processing error occurs /// </summary> /// <param name="disposition">How the error should be handled</param> /// <param name="defaultBuffer">The default output buffer</param> /// <param name="errorBuffer">The error output buffer</param> /// <param name="failingColumnInfo">The information for the problematic column</param> /// <param name="ex">The exception caught from processing (optional)</param> private void HandleProcessingError(DTSRowDisposition disposition, PipelineBuffer defaultBuffer, PipelineBuffer errorBuffer, ColumnInfo failingColumnInfo, Exception ex) { switch (disposition) { case DTSRowDisposition.RD_RedirectRow: if (errorBuffer == null) throw new InvalidOperationException("There must be an error output defined if redirection was specified"); // Add a row to the error buffer. errorBuffer.AddRow(); // Get the values from the default buffer // and copy them to the error buffer. var errorOutputColumns = GetErrorOutputColumns().ToArray(); foreach (IDTSOutputColumn100 column in errorOutputColumns) { ColumnInfo copiedColumnInfo = GetColumnInfo(column.Name); if (copiedColumnInfo != null) errorBuffer[copiedColumnInfo.ErrorOuputBufferColumnIndex] = defaultBuffer[copiedColumnInfo.OuputBufferColumnIndex]; } // Set the error information. int errorCode = (ex == null ? 0 : System.Runtime.InteropServices.Marshal.GetHRForException(ex)); errorBuffer.SetErrorInfo(errorOutputID, errorCode, failingColumnInfo.OutputColumn.LineageID); // Remove the row that was added to the default buffer. defaultBuffer.RemoveRow(); break; case DTSRowDisposition.RD_FailComponent: throw new Exception(String.Format("There was an issue with column: {0}", failingColumnInfo.OutputColumn.Name), ex); } }
// todo: // CacheMode // https://blogs.msdn.microsoft.com/mattm/2009/01/02/api-sample-lookup-transform/ public IDTSComponentMetaData100 AddComp_Lookup(string componentName, string conManName, string sqlComm, IDTSOutput100 outCols, List <string> joinColumns, Dictionary <string, string> newColumns, DTSRowDisposition rowDisposition = DTSRowDisposition.RD_IgnoreFailure, int redirectRowsToNoMatchOutput = 0 ) { // Create IDTSComponentMetaData100 Comp = dmp.ComponentMetaDataCollection.New(); Comp.ComponentClassID = "Microsoft.Lookup"; // Instantiate CManagedComponentWrapper Inst = Comp.Instantiate(); Inst.ProvideComponentProperties(); Comp.Name = componentName; Comp.Description = "Dodany Lookup"; // Connect IDTSPath100 pth = dmp.PathCollection.New(); pth.AttachPathAndPropagateNotifications(outCols, Comp.InputCollection[0]); // GetConnectionManager ConnectionManager cm = prj.ConnectionManagerItems[conManName + ".conmgr"].ConnectionManager; Comp.RuntimeConnectionCollection[0].ConnectionManager = DtsConvert.GetExtendedInterface(cm); Comp.RuntimeConnectionCollection[0].ConnectionManagerID = cm.ID; // Parametrize #1 IDTSOutput100 lmo = Comp.OutputCollection["Lookup Match Output"]; lmo.ErrorRowDisposition = rowDisposition; // Cache Type: // 0 = Full // 1 = Partial // 2 = None Inst.SetComponentProperty("CacheType", 0); // 0 = FailComponent, IgnoreFailure, RedirectRowsToErrorOutput // 1 = RedirectRowsToNoMatchOutput Inst.SetComponentProperty("NoMatchBehavior", redirectRowsToNoMatchOutput); Inst.SetComponentProperty("SqlCommand", sqlComm); // MetaData Inst.AcquireConnections(null); Inst.ReinitializeMetaData(); Inst.ReleaseConnections(); // Parametrize #2 - Join Columns IDTSInput100 lkpInput = Comp.InputCollection[0]; IDTSInputColumnCollection100 lkpInputCols = lkpInput.InputColumnCollection; IDTSVirtualInput100 lkpVirtInput = lkpInput.GetVirtualInput(); IDTSVirtualInputColumnCollection100 lkpVirtInputCols = lkpVirtInput.VirtualInputColumnCollection; foreach (string columnName in joinColumns) { IDTSVirtualInputColumn100 vColumn = lkpVirtInputCols[columnName]; IDTSInputColumn100 inputColumn = Inst.SetUsageType(lkpInput.ID, lkpVirtInput, vColumn.LineageID, DTSUsageType.UT_READONLY); Inst.SetInputColumnProperty(lkpInput.ID, inputColumn.ID, "JoinToReferenceColumn", columnName); } // Parametrize #3 - New Lookup Columns IDTSOutput100 lookupMatchOutput = Comp.OutputCollection["Lookup Match Output"]; foreach (string srcCol in newColumns.Keys) { string newColumnName = newColumns[srcCol]; string description = string.Format("Copy of {0}", srcCol); IDTSOutputColumn100 outputColumn = Inst.InsertOutputColumnAt(lookupMatchOutput.ID, 0, newColumnName, description); Inst.SetOutputColumnProperty(lookupMatchOutput.ID, outputColumn.ID, "CopyFromReferenceColumn", srcCol); } // Return return(Comp); }
/// <summary> /// Called at run time for source components and transformation components with /// asynchronous outputs to let these components add rows to the output buffers. /// </summary> /// <param name="outputs">The number of elements in the outputIDs and buffers arrays.</param> /// <param name="outputIDs">An array of Microsoft.SqlServer.Dts.Pipeline.Wrapper.IDTSOutput100 ID's.</param> /// <param name="buffers">An array of Microsoft.SqlServer.Dts.Pipeline.PipelineBuffer objects.</param> public override void PrimeOutput(int outputs, int[] outputIDs, PipelineBuffer[] buffers) { // Determine which buffer is for regular output, and which is for error output PipelineBuffer errorBuffer = null; PipelineBuffer defaultBuffer = null; for (int outputIndex = 0; outputIndex < outputs; outputIndex++) { if (outputIDs[outputIndex] == errorOutputID) { errorBuffer = buffers[outputIndex]; } else { defaultBuffer = buffers[outputIndex]; } } var cursor = GetCollectionCursor(ComponentMetaData.CustomPropertyCollection[COLLECTION_NAME_PROP_NAME].Value); var defaultOutputColumns = GetDefaultOutputColumns().ToArray(); foreach (BsonDocument document in cursor) { ColumnInfo failingColumnInfo = null; try { defaultBuffer.AddRow(); foreach (ColumnInfo columnInfo in this.columnInformata) { failingColumnInfo = columnInfo; if (document.Contains(columnInfo.ColumnName) && document[columnInfo.ColumnName] != null) { if (document.GetValue(columnInfo.ColumnName).IsBsonNull) { defaultBuffer.SetNull(columnInfo.OuputBufferColumnIndex); } else { var value = GetValue(document, columnInfo); try { defaultBuffer[columnInfo.OuputBufferColumnIndex] = value; } catch (DoesNotFitBufferException ex) { if (failingColumnInfo.OutputColumn.TruncationRowDisposition == DTSRowDisposition.RD_IgnoreFailure) { if (value is string) { defaultBuffer[columnInfo.OuputBufferColumnIndex] = value.ToString().Substring(0, columnInfo.OutputColumn.Length); } else { ComponentMetaData.FireWarning(0, "MongoDataSource", string.Format("Truncation of column {0} failed, as truncation of type {1} currently unsupported.", columnInfo.OutputColumn.Name, value.GetType().FullName), String.Empty, 0); } } else { throw ex; } } } } else { defaultBuffer.SetNull(columnInfo.OuputBufferColumnIndex); } } } catch (Exception ex) { DTSRowDisposition disposition = DTSRowDisposition.RD_NotUsed; if (ex is DoesNotFitBufferException) { disposition = failingColumnInfo.OutputColumn.TruncationRowDisposition; } else { disposition = failingColumnInfo.OutputColumn.ErrorRowDisposition; } HandleProcessingError(disposition, defaultBuffer, errorBuffer, failingColumnInfo, ex); } } if (defaultBuffer != null) { defaultBuffer.SetEndOfRowset(); } if (errorBuffer != null) { errorBuffer.SetEndOfRowset(); } }