/// <summary> /// Initializes a new instance of the PassThreadState class. /// </summary> /// <param name="columnToProcess">the OutputColumn that is to be processed (hashed)</param> /// <param name="buffer">the PipelineBuffer that is being read</param> /// <param name="metaData">the Component MetaData that is being processed</param> /// <param name="threadReset">the Event that is to be manually reset to indicate completion</param> /// <param name="safeNullHandling">the flag to indicate whether to have safe null handling</param> public PassThreadState(OutputColumn columnToProcess, PipelineBuffer buffer, IDTSComponentMetaData metaData, ManualResetEvent threadReset, bool safeNullHandling, bool millisecondHandling) { this.ColumnToProcess = columnToProcess; this.Buffer = buffer; this.MetaData = metaData; this.ThreadReset = threadReset; this.SafeNullHandling = safeNullHandling; this.MillisecondHandling = millisecondHandling; }
/// <summary> /// This creates the hash value from a thread /// </summary> /// <param name="state">this is the thread state object that is passed</param> public static void CalculateHash(OutputColumn columnToProcess, PipelineBuffer buffer, bool safeNullHandling, bool millisecondHandling) { byte[] inputByteBuffer = new byte[1000]; Int32 bufferUsed = 0; string nullHandling = String.Empty; uint blobLength = 0; Int32 columnToProcessID = 0; DataType columnDataType = DataType.DT_NULL; // Step through each input column for that output column for (int j = 0; j < columnToProcess.Count; j++) { columnToProcessID = columnToProcess[j].ColumnId; // Only call this once, as it appears to be "slow". columnDataType = columnToProcess[j].ColumnDataType; // Skip NULL values, as they "don't" exist... if (!buffer.IsNull(columnToProcessID)) { nullHandling += "N"; switch (columnDataType) //buffer.GetColumnInfo(columnToProcessID).DataType) { case DataType.DT_BOOL: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetBoolean(columnToProcessID)); break; case DataType.DT_IMAGE: blobLength = buffer.GetBlobLength(columnToProcessID); Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetBlobData(columnToProcessID, 0, (int)blobLength)); nullHandling += blobLength.ToString(); break; case DataType.DT_BYTES: byte[] bytesFromBuffer = buffer.GetBytes(columnToProcessID); Utility.Append(ref inputByteBuffer, ref bufferUsed, bytesFromBuffer); nullHandling += bytesFromBuffer.GetLength(0).ToString(); break; case DataType.DT_CY: case DataType.DT_DECIMAL: case DataType.DT_NUMERIC: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetDecimal(columnToProcessID)); break; case DataType.DT_DBTIMESTAMPOFFSET: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetDateTimeOffset(columnToProcessID), millisecondHandling); break; case DataType.DT_DBDATE: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetDate(columnToProcessID), millisecondHandling); break; case DataType.DT_DATE: case DataType.DT_DBTIMESTAMP: case DataType.DT_DBTIMESTAMP2: case DataType.DT_FILETIME: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetDateTime(columnToProcessID), millisecondHandling); break; case DataType.DT_DBTIME: case DataType.DT_DBTIME2: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetTime(columnToProcessID)); break; case DataType.DT_GUID: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetGuid(columnToProcessID)); break; case DataType.DT_I1: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetSByte(columnToProcessID)); break; case DataType.DT_I2: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetInt16(columnToProcessID)); break; case DataType.DT_I4: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetInt32(columnToProcessID)); break; case DataType.DT_I8: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetInt64(columnToProcessID)); break; case DataType.DT_NTEXT: case DataType.DT_STR: case DataType.DT_TEXT: case DataType.DT_WSTR: String stringFromBuffer = buffer.GetString(columnToProcessID); Utility.Append(ref inputByteBuffer, ref bufferUsed, stringFromBuffer, Encoding.UTF8); nullHandling += stringFromBuffer.Length.ToString(); break; case DataType.DT_R4: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetSingle(columnToProcessID)); break; case DataType.DT_R8: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetDouble(columnToProcessID)); break; case DataType.DT_UI1: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetByte(columnToProcessID)); break; case DataType.DT_UI2: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetUInt16(columnToProcessID)); break; case DataType.DT_UI4: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetUInt32(columnToProcessID)); break; case DataType.DT_UI8: Utility.Append(ref inputByteBuffer, ref bufferUsed, buffer.GetUInt64(columnToProcessID)); break; case DataType.DT_EMPTY: case DataType.DT_NULL: default: break; } } else { nullHandling += "Y"; } } if (safeNullHandling) { Utility.Append(ref inputByteBuffer, ref bufferUsed, nullHandling, Encoding.UTF8); } // Ok, we have all the data in a Byte Buffer // So now generate the Hash byte[] hash; switch (columnToProcess.HashType) { case Martin.SQLServer.Dts.MultipleHash.HashTypeEnumerator.None: hash = new byte[1]; break; case Martin.SQLServer.Dts.MultipleHash.HashTypeEnumerator.MD5: case Martin.SQLServer.Dts.MultipleHash.HashTypeEnumerator.RipeMD160: case Martin.SQLServer.Dts.MultipleHash.HashTypeEnumerator.SHA1: case Martin.SQLServer.Dts.MultipleHash.HashTypeEnumerator.SHA256: case Martin.SQLServer.Dts.MultipleHash.HashTypeEnumerator.SHA384: case Martin.SQLServer.Dts.MultipleHash.HashTypeEnumerator.SHA512: case Martin.SQLServer.Dts.MultipleHash.HashTypeEnumerator.CRC32: case Martin.SQLServer.Dts.MultipleHash.HashTypeEnumerator.CRC32C: case Martin.SQLServer.Dts.MultipleHash.HashTypeEnumerator.FNV1a32: case Martin.SQLServer.Dts.MultipleHash.HashTypeEnumerator.FNV1a64: case Martin.SQLServer.Dts.MultipleHash.HashTypeEnumerator.MurmurHash3a: case Martin.SQLServer.Dts.MultipleHash.HashTypeEnumerator.xxHash: hash = columnToProcess.HashObject.ComputeHash(inputByteBuffer, 0, bufferUsed); break; default: hash = new byte[1]; break; } switch (columnToProcess.OutputHashDataType) { case MultipleHash.OutputTypeEnumerator.Binary: buffer.SetBytes(columnToProcess.OutputColumnId, hash); break; case MultipleHash.OutputTypeEnumerator.Base64String: buffer.SetString(columnToProcess.OutputColumnId, System.Convert.ToBase64String(hash, 0, hash.Length)); break; case MultipleHash.OutputTypeEnumerator.HexString: buffer.SetString(columnToProcess.OutputColumnId, String.Format("0x{0}", ByteArrayToHexViaLookup32(hash))); break; } }