1850 lines
92 KiB
C
1850 lines
92 KiB
C
//
|
||
// DTSPump.h
|
||
// Header file for the OLEDB DTSDataPump Service Provider.
|
||
// Copyright 1997 Microsoft Corporation
|
||
//
|
||
#ifndef DTSDataPump_H_
|
||
#pragma option push -b -a8 -pc -A- /*P_O_Push*/
|
||
#define DTSDataPump_H_
|
||
|
||
#ifndef DTSDataPumpVersion_Major
|
||
#define DTSDataPumpVersion_Major 1
|
||
#define DTSDataPumpVersion_Minor 0
|
||
#endif // DTSDataPumpVersion_Major
|
||
|
||
#ifndef DTSDataPump_VersionOnly
|
||
|
||
// The default Blob size used in this version of the DataPump.
|
||
// May be overridden on a per-Transform or per-column basis.
|
||
#define DTS_DEFAULT_INMEMORY_BLOB_SIZE (1024 * 1024)
|
||
|
||
// Default number of successful InsertRows which will be Committed if supported by provider.
|
||
// Currently set to 0 which means not to do a commit until all rows have been transferred.
|
||
#define DTS_DEFAULT_InsertCommitSize 0
|
||
|
||
///////////////////////////////////////////////////////////////////////////////////////
|
||
// CPP and OleAut Enumerations and constants.
|
||
///////////////////////////////////////////////////////////////////////////////////////
|
||
#ifndef DTSDataPump_CONSTANTS_
|
||
#define DTSDataPump_CONSTANTS_
|
||
|
||
// To avoid the need to cast on bitwise operations (which defeats typesafety anyway),
|
||
// define the datatype as DWORD for C/CPP. OleAut languages don't do typechecking
|
||
// and organize by the enum name.
|
||
#ifdef DTSDataPump_ODL_
|
||
#define DP_ENUM_BEGIN(tdef, hstring) [helpcontext(H_##tdef), helpstring(hstring)] enum tdef
|
||
// item = value, ...
|
||
#define DP_ENUM_END(tdef) tdef, *LP##tdef
|
||
#else
|
||
#define DP_ENUM_BEGIN(tdef, hstring) DWORD tdef, *LP##tdef; enum tag##tdef
|
||
// item = value, ...
|
||
#define DP_ENUM_END(tdef)
|
||
#endif
|
||
|
||
typedef DP_ENUM_BEGIN(DTSDataPumpError, "Error ranges for DTSDataPump execution") {
|
||
DTSDataPump_E_NotImplemented = 0x2000,
|
||
DTSDataPump_E_RowsetsAlreadySet = 0x2001,
|
||
DTSDataPump_E_TransformsAlreadySet = 0x2002,
|
||
DTSDataPump_E_DestRowsetNotSupplied = 0x2003,
|
||
DTSDataPump_E_RowsetsNotSupplied = 0x2004,
|
||
DTSDataPump_E_SourceColumnsRequired = 0x2005,
|
||
DTSDataPump_E_ColCountButNoCols = 0x2006,
|
||
DTSDataPump_E_MismatchColOrdAndName = 0x2007,
|
||
DTSDataPump_E_ColumnNameNotFound = 0x2008,
|
||
DTSDataPump_E_ColumnOutOfRange = 0x2009,
|
||
DTSDataPump_E_DestColumnAlreadySpecified = 0x200a,
|
||
DTSDataPump_E_IDataConvertRequired = 0x200b,
|
||
DTSDataPump_E_NullVariantIUnknown = 0x200c,
|
||
DTSDataPump_E_NotReentrant = 0x200d,
|
||
DTSDataPump_E_RowsetChangeMustInsert = 0x200e,
|
||
DTSDataPump_E_DataPumpNotReentrant = 0x200f,
|
||
DTSDataPump_E_DestColumnReadOnly = 0x2010,
|
||
DTSDataPump_E_MustSpecifyDestOrTransform = 0x2011,
|
||
DTSDataPump_E_BadTransformFlag = 0x2012,
|
||
DTSDataPump_E_BadTransformStatusReturned = 0x2013,
|
||
DTSDataPump_E_TransformServerException = 0x2014,
|
||
DTSDataPump_E_CannotRebindColumn = 0x2015,
|
||
DTSDataPump_E_InvalidFetchBufferSize = 0x2016,
|
||
DTSDataPump_E_InvalidDTSBindMode = 0x2017,
|
||
DTSDataPump_E_SourceBlobBinding = 0x2018,
|
||
DTSDataPump_E_NonBlobStorageBind = 0x2019,
|
||
DTSDataPump_E_LookupDupName = 0x201a,
|
||
|
||
DTSDataPump_E_DestinationBlobBinding = 0x2020,
|
||
|
||
DTSDataPump_E_Copy_NeedSrcAndDestColumns = 0x2024,
|
||
DTSDataPump_E_Copy_ValidateSchemaError = 0x2025,
|
||
|
||
DTSDataPump_E_Convert_DestNotNull = 0x2026,
|
||
DTSDataPump_E_Convert_BadBindInfo = 0x2027,
|
||
DTSDataPump_E_Convert_DestOverflow = 0x2028,
|
||
DTSDataPump_E_Convert_SourceInvalidVariant = 0x2029,
|
||
DTSDataPump_E_Convert_SourceInvalidLength = 0x202a,
|
||
DTSDataPump_E_Convert_ConversionInvalid = 0x202b,
|
||
DTSDataPump_E_Convert_ConversionFailed = 0x202c,
|
||
DTSDataPump_E_Convert_ProviderOwnedTypeMismatch = 0x202d,
|
||
DTSDataPump_E_Convert_BlobStorageNoInterface = 0x202e,
|
||
|
||
DTSDataPump_E_AxScript_RequiredParams = 0x2040,
|
||
DTSDataPump_E_AxScript_ValidateSchemaError = 0x2041,
|
||
DTSDataPump_E_AxScript_ParseError = 0x2042,
|
||
DTSDataPump_E_AxScript_BadTransformFunction = 0x2043,
|
||
DTSDataPump_E_AxScript_CantChangeSrcCols = 0x2044,
|
||
DTSDataPump_E_AxScript_CantResetAfterInitialize = 0x2045,
|
||
DTSDataPump_E_AxScript_CantInitializeEngine = 0x2046,
|
||
DTSDataPump_E_AxScript_RunTimeError = 0x2047,
|
||
|
||
DTSDataPump_E_AutoBufferInterfaceNotSupported = 0x2051,
|
||
DTSDataPump_E_InvalidSpecifyBlobDefaults = 0x2051,
|
||
DTSDataPump_E_LineageVariableNotFound = 0x2052,
|
||
DTSDataPump_E_LastRowCantBeLessThanFirst = 0x2053,
|
||
|
||
DTSDataPump_E_DDQ_NeedTransformStatus = 0x2060,
|
||
DTSDataPump_E_DDQ_NeedInsertQuery = 0x2061,
|
||
DTSDataPump_E_DDQ_NeedUpdateQuery = 0x2062,
|
||
DTSDataPump_E_DDQ_NeedDeleteQuery = 0x2063,
|
||
DTSDataPump_E_DDQ_NeedUserQuery = 0x2064,
|
||
DTSDataPump_E_DDQ_InformationNotSet = 0x2065,
|
||
DTSDataPump_E_DDQ_BadTransformStatusContext = 0x2065,
|
||
DTSDataPump_E_DDQ_DestColumnNotTransformed = 0x2066,
|
||
DTSDataPump_E_DDQ_DestColumnNeedsLength = 0x2067,
|
||
DTSDataPump_E_DDQ_DestDoesNotSupportSQL = 0x2068,
|
||
|
||
} DP_ENUM_END(DTSDataPumpError);
|
||
|
||
// These allow definition of how the transform will proceed.
|
||
typedef DP_ENUM_BEGIN(DTSTransformFlags, "Flags (int or long) controlling Transform") {
|
||
// No flags are specified; essentially, the conversion must be between exact types.
|
||
// Note that this allows string <--> nonstring conversions, because every nonstring datatype
|
||
// has a meaningful string representation. This may be overridden by RequireExactType,
|
||
// which is even stricter.
|
||
DTSTransformFlag_Strict = 0x00000000,
|
||
|
||
// This flag means that IDTSDataPumpTransform::ValidateSchema should allow the transfer to proceed
|
||
// even if there are potential overflows, under the assumption that the consumer is aware of this but
|
||
// knows the source values are all (or mostly) within the destination column<6D>s range. Any overflows during
|
||
// transformation will cause the row to be exceptioned. This flag is generally of interest only to
|
||
// the IID_IDTSDataPumpTransformCopy implementation, as this is a direct copy, whereas other
|
||
// implementations would probably convert the values or determine validity on a specific case-by-case basis.
|
||
// This value is also used for date/time conversions which result in loss, such as DATE -> DBTIME,
|
||
// where a subset of the source value is still meaningful.
|
||
DTSTransformFlag_AllowDemotion = 0x00000001,
|
||
|
||
// This flag means that IDTSDataPumpTransform::ValidateSchema should allow the transfer to proceed
|
||
// when there is promotion in the data range when moving from the source to the destination types,
|
||
// such as I2->I4 or I4->float/double. Note that in some cases, such as I4->R4, the data range
|
||
// increases but at the loss of some digits of precision.
|
||
// If AllowLossless is specified, this is allowed by the Transform.
|
||
DTSTransformFlag_AllowPromotion = 0x00000002,
|
||
|
||
// This flag allows column (w)char or byte data to be truncated silently, such as when moving data
|
||
// from a char(60) to a char(40) column. AllowDemotion is implied but overflow will be
|
||
// silently truncated instead of causing an error.
|
||
DTSTransformFlag_AllowStringTruncation = 0x00000004,
|
||
|
||
// This flag means that IDTSDataPumpTransform::ValidateSchema should allow the transfer to proceed
|
||
// even in the event that the source is a floating-point or numeric/decimal type and the destination
|
||
// is an integral type. This is a numeric flavour of AllowDemotion and will not cause an error
|
||
// (integer overflow will still be an error; i.e. left-of-decimal digits are significant).
|
||
DTSTransformFlag_AllowNumericTruncation = 0x00000008,
|
||
|
||
// This flag means that IDTSDataPumpTransform::ValidateSchema should allow the transfer to proceed
|
||
// even if the source column allows NULL values and the destination column does not. As with
|
||
// AllowDemotion, errors may be encountered during a transform.
|
||
// If AllowLossless is specified, this is allowed by the Transform if going from nonNULLable to NULLable.
|
||
DTSTransformFlag_AllowNullChange = 0x00000010,
|
||
|
||
// This flag means that IDTSDataPumpTransform::ValidateSchema should allow the transfer to proceed
|
||
// even in the event that the source and destination have a signed vs. unsigned mismatch. As with
|
||
// AllowDemotion, errors may be encountered during a transform.
|
||
// If AllowLossless is specified, this is allowed by the Transform when going from unsigned to signed
|
||
// with promotion (e.g. UI2 -> I4).
|
||
DTSTransformFlag_AllowSignChange = 0x00000020,
|
||
|
||
// Require that the destination column's datatype be exactly the same as the source column's
|
||
// (including length or precision/scale, fixed vs. variable length, sign, and nullability).
|
||
// This overrides any other flags specified for column conversion validation.
|
||
// Cannot be specified with ForceConvert.
|
||
DTSTransformFlag_RequireExactType = 0x00000040,
|
||
|
||
// Allow the conversion to proceed at all times, even when the source and destination types are
|
||
// fundamentally different. Currently this applies to:
|
||
// <nonchar> <--> bytes: Does a bitwise copy; caveats apply for endian, machine representations.
|
||
// int/real <--> date: DATE is a double so this just converts between int and double.
|
||
// real <--> date: DATE is a double so this just copies.
|
||
// Cannot be specified with RequireExactType.
|
||
DTSTransformFlag_ForceConvert = 0x00000080,
|
||
|
||
// Causes the TransformServer to not ClearBindingData() the destination-row storage
|
||
// for the columns in this Transform during OnRowComplete(). This allows the
|
||
// destination row's values to be reused by the next transform.
|
||
DTSTransformFlag_PreserveDestRows = 0x00000100,
|
||
|
||
// Causes the TransformServer to allow all conversions for which a lossless conversion is
|
||
// possible - e.g. Promotion, nonNULLable -> NULLable, unsigned -> promoted signed.
|
||
DTSTransformFlag_AllowLosslessConversion = 0x00000200,
|
||
|
||
// No flags are specified; essentially, the conversion must be between exact types.
|
||
// Note that this allows string <--> nonstring conversions, because every nonstring datatype
|
||
// has a meaningful string representation. This may be overridden by RequireExactType.
|
||
DTSTransformFlag_Default = (DTSTransformFlag_AllowDemotion | DTSTransformFlag_AllowPromotion | DTSTransformFlag_AllowStringTruncation | DTSTransformFlag_AllowNumericTruncation | DTSTransformFlag_AllowNullChange | DTSTransformFlag_AllowSignChange)
|
||
|
||
} DP_ENUM_END(DTSTransformFlags);
|
||
|
||
// Status returned from a Transform operation.
|
||
// All "normal" errors from DTSDataPumpTransform::Execute should be returned as
|
||
// one of these flags, with a SUCCEEDED HRESULT (possibly with the addition of
|
||
// OLEDB Error Records via the IDTSErrorRecords interface passed to
|
||
// IDTSDataPumpTransform::AddVariable). A FAILED HRESULT returned from
|
||
// DTSDataPumpTransform::Execute indicates an unrecoverable error and aborts
|
||
// the DataPump.
|
||
typedef DP_ENUM_BEGIN(DTSTransformStatus, "Return value (int or long) from ActiveX Scripting Transform") {
|
||
// Default; conversions (if any) succeeded; write the row to destination if
|
||
// specified, without calling any error handlers. Default is to do Insert;
|
||
// this may be overridden for data-driven queries by other flags to do Insert,
|
||
// Update, Delete, or UserQuery for a user-defined ad-hoc query.
|
||
DTSTransformStat_OK = 0x00000001,
|
||
|
||
// Success with additional info, which the app may want to process further
|
||
// by reading its pvTransformUserData (if it shares that knowledge with the
|
||
// transform server) or thru OLEDB Error Records; therefore, the Pump will
|
||
// call the ErrorSink if one was specified, but does not increment the error
|
||
// row count. The DTSTransformStatus result of the operation is passed to
|
||
// the ErrorSink, so the app can switch on this bit.
|
||
DTSTransformStat_Info = 0x00001000,
|
||
|
||
// Write row if destination specified; also call ErrorSink with Info.
|
||
DTSTransformStat_OKInfo = 0x00001001,
|
||
|
||
// Abort further processing of this row, for non-error reasons.
|
||
DTSTransformStat_SkipRow = 0x00000002,
|
||
|
||
// Abort further processing of this row, and calls ErrorSink with Info.
|
||
DTSTransformStat_SkipRowInfo = 0x00001002,
|
||
|
||
// Do not fetch the next row; re-execute all transforms against the current
|
||
// source and destination rows. No initialization is done to the destination
|
||
// row, so this could be used to generate multiple output rows from a single
|
||
// input row. Subsequent transforms are still executed unless a SkipRow* flag
|
||
// is also present.
|
||
DTSTransformStat_SkipFetch = 0x00000004,
|
||
|
||
// Do not write the current row to destination. Usually used to fetch the next
|
||
// source row to generate a simple aggregate. Subsequent transforms are still
|
||
// executed unless a SkipRow* flag is also present. DTSTransformStat_SkipInsert
|
||
// forces DTSTransformFlag_PreserveDestRows behaviour for the row for which it
|
||
// is specified.
|
||
DTSTransformStat_SkipInsert = 0x00000008,
|
||
|
||
// The following 4 flags are not compatible together. They execute the
|
||
// similarly-named statement passed to SetRowsetAndQueries on the Destination,
|
||
// with values from the currently transformed Destination Row.
|
||
DTSTransformStat_InsertQuery = 0x00000010,
|
||
DTSTransformStat_UpdateQuery = 0x00000020,
|
||
DTSTransformStat_DeleteQuery = 0x00000040,
|
||
DTSTransformStat_UserQuery = 0x00000080,
|
||
|
||
// May be bit-OR'd into the following error returns.
|
||
DTSTransformStat_Error = 0x00002000,
|
||
|
||
// Abort further processing of this row due to error and call the error sink,
|
||
// but do not write to exception file. Should be handled by the ErrorSink.
|
||
DTSTransformStat_ErrorSkipRow = 0x00002002,
|
||
|
||
// Abort further processing of this row as an exception and call the error sink,
|
||
// and write this row to exception file. Should be handled by the ErrorSink.
|
||
// Note this bit does not map to any non-error bits.
|
||
DTSTransformStat_ExceptionRow = 0x00002100,
|
||
|
||
// Or<4F>d with prior bits to abort processing any further rows and return
|
||
// DTSTransformExec_AbortPump from IDTSDataPump::Execute().
|
||
// This does not include the Error bit so &'ing with it will only return
|
||
// TRUE for this bit.
|
||
DTSTransformStat_AbortPump = 0x00004000,
|
||
|
||
// Transform determined that this row is the last one to be operated on,
|
||
// so allows the pump to be aborted "normally" (without signifying an error).
|
||
// May be or'd with other bits to skip the current row; otherwise it will go
|
||
// to the next transforms and then write it to destination (in accordance with
|
||
// how the following transforms specify).
|
||
DTSTransformStat_NoMoreRows = 0x00008000,
|
||
|
||
} DP_ENUM_END(DTSTransformStatus);
|
||
|
||
// Status returned from an IDataPump::Execute operation.
|
||
typedef DP_ENUM_BEGIN(DTSExecuteStatus, "Return value (int or long) from DataPump Execution") {
|
||
// All rows copied (or skipped) without error.
|
||
DTSTransformExec_OK = 0x00000000,
|
||
|
||
// Bit-OR<4F>d into the following error returns.
|
||
DTSTransformExec_Error = 0x00001000, // Bit-or<6F>d into following
|
||
|
||
// Pump continued to completion but errors were encountered
|
||
DTSTransformExec_OKErrors = 0x00001001,
|
||
|
||
// Pump aborted because too many rows had errors.
|
||
DTSTransformExec_ErrorCountExceeded = 0x00001002,
|
||
|
||
// Pump aborted due to Transform request or ErrorSink return.
|
||
DTSTransformExec_AbortPump = 0x00001004,
|
||
} DP_ENUM_END(DTSExecuteStatus);
|
||
|
||
#endif // DTSDataPump_CONSTANTS_
|
||
|
||
////////////////////////////////////////////
|
||
// CPP-only definitions
|
||
////////////////////////////////////////////
|
||
|
||
#ifndef DTSDataPump_ODL_
|
||
|
||
// Define parameter usage.
|
||
#define DP_IN
|
||
#define DP_OUT
|
||
#define DP_INOUT
|
||
|
||
#ifdef NONAMELESSUNION
|
||
#define DP_UNION_NAME(u) u
|
||
#else
|
||
#define DP_UNION_NAME(u)
|
||
#endif
|
||
|
||
// For safety, struct initialization values are set in ctors for C++ clients.
|
||
#if !defined(__cplusplus) && !defined(DP_NO_AUTOCTOR)
|
||
#define DP_NO_AUTOCTOR
|
||
#endif
|
||
|
||
// These are the conversion flags indicating what may happen during an individual column
|
||
// Convert() call, and accounts for the column lengths, nullability, sign, etc.
|
||
// See DTSTransformFlags for a more detailed discussion of the similarly-named TransformFlag
|
||
// which will allow conversion to proceed when these conditions are present.
|
||
// Keys:
|
||
// <T> - TransformFlag is available to explicitly allow this.
|
||
// <E> - Error may be encountered during Convert()
|
||
// <F> - Fatal; Convert() will error as unsupported or with overflow.
|
||
//
|
||
typedef DP_ENUM_BEGIN(DTSConvertFlags, "DTSConvertFlags") {
|
||
// The conversion is between columns of identical type, length or precision/scale,
|
||
// and nullability, or is between text and another type, with the text being of
|
||
// sufficient length for a representation of that datatype. Errors should not be
|
||
// encountered during Convert() unless a text conversion contains invalid data.
|
||
DTSConvertFlag_ExactType = 0x00000000,
|
||
|
||
// The conversion will promote the range of data from source to destination
|
||
// (e.g. I4 -> I2, [var]char -> longer [var]char, numeric(x, y) -> numeric(x+1, y+1)).
|
||
// <T>
|
||
DTSConvertFlag_Promotion = 0x00000001,
|
||
|
||
// Conversion will demote (e.g. I4 -> I2); overflow error possible.
|
||
// <T, E>
|
||
DTSConvertFlag_Demotion = 0x00000002,
|
||
|
||
// Conversion may do string or byte truncation; truncation error possible if
|
||
// this flag is not specified on Convert().
|
||
// <T, E>
|
||
DTSConvertFlag_StringTruncation = 0x00000004,
|
||
|
||
// Conversion may do integral rounding from float or numeric, or move a larger
|
||
// scale into a smaller scale (both cases resulting in truncation of digits to
|
||
// the right of the decimal point). This is also flagged when moving from integral
|
||
// or numeric to float/double when source precision is greater than FLT/DBL_DIG.
|
||
// <T>
|
||
DTSConvertFlag_NumericTruncation = 0x00000008,
|
||
|
||
// Conversion may try to put NULL source data into a NonNULL destination column,
|
||
// which will error, or vice-versa, which will be safe.
|
||
// <T, E>
|
||
DTSConvertFlag_NullChange = 0x00000010,
|
||
|
||
// Conversion may try to put a signed value int/float into an unsigned destination,
|
||
// or vice-versa. This may error if the source value is negative and destination
|
||
// is unsigned, or if the source is unsigned and its value is larger than the
|
||
// signed destination's maximum signed value (overflow).
|
||
// <T, E>
|
||
DTSConvertFlag_SignChange = 0x00000020,
|
||
|
||
// Destination column size is too short for a meaningful conversion from source
|
||
// column type.
|
||
// <F>
|
||
DTSConvertFlag_DestTooShort = 0x00000040,
|
||
|
||
// Source column size is too short for a meaningful conversion to destination
|
||
// column type.
|
||
// <F>
|
||
DTSConvertFlag_SourceTooShort = 0x00000080,
|
||
|
||
// Source and destination datatypes are not really compatible, but conversion can be forced.
|
||
// <T>
|
||
DTSConvertFlag_ForceConvert = 0x00000100,
|
||
|
||
// Conversion fails because of bad or incompatible column types.
|
||
// <F>
|
||
DTSConvertFlag_Unsupported = 0x00001000,
|
||
|
||
} DP_ENUM_END(DTSConvertFlags);
|
||
|
||
// Binding modes for column data; returned from IDTSDataPumpTransform::ValidateSchema
|
||
// via DTSTransformColumnInfo. Normally the DataPump default handling does not need to
|
||
// be changed, but for Blob ((DBCOLUMNFLAGS_ISLONG) columns, custom Transforms are able
|
||
// to adjust bindings to maximize performance.
|
||
//
|
||
typedef DP_ENUM_BEGIN(DTSBindMode, "DTSBindMode") {
|
||
// Indicates data should be bound "in-memory, out of line". Currently this is only supported
|
||
// by the OLEDB specification for variable-length types: DBTYPE_((W)STR|BYTES); therefore,
|
||
// the DataPump will error if it is specified for other types. DTSBindMode_(Client|Provider)Owned
|
||
// must be specified with DTSBindMode_Byref.
|
||
//
|
||
// For source, the returned data will be a direct pointer to the provider's data if
|
||
// DTSBindMode_ProviderOwned is specified (in which case it must not be free'd or written to),
|
||
// or a CoTaskMemAlloc()'d pointer if DTSBindMode_ClientOwned is specified (in which case it
|
||
// is the client's property and must be freed).
|
||
//
|
||
// For destination, the transformation server must place the data pointer in
|
||
// pDestColumnInfo->pvRowData. If DTSBindMode_ClientOwned is specified, then the data
|
||
// is assumed to require freeing after the InsertRow operation completes. The DataPump
|
||
// will never perform a non-Byref, in-memory destination binding for a Blob, so this flag
|
||
// must be specified unless a Storage Object is used.
|
||
//
|
||
DTSBindMode_Byref = 0x00000001,
|
||
|
||
// Default "in-memory, inline" binding mode; space for the source and destination data, including
|
||
// the full length of a DBTYPE_((W)STR|BYTES) column, is allocated in rgColumnData[ii].pvData and
|
||
// passed to IDTSDataPumpTransform::Execute.
|
||
//
|
||
// For a BLOB (DBCOLUMNFLAGS_ISLONG) column, IDTSDataPumpTransform::ValidateSchema returns
|
||
// the length to use for this binding in ppDTSColBinding[ii].cbInMemoryBlobSize. This will
|
||
// result in a separate allocation for that Blob column (i.e. multiple Blobs are not
|
||
// allocated within a single contiguous row).
|
||
//
|
||
// On fetch from Source, the DBSTATUS in the binding will indicate whether the data was
|
||
// truncated; it is up to the Transform server how (or if) this is handled.
|
||
//
|
||
// For performance reasons, this flag should not be specified for non-Blob (W)STR|BYTES
|
||
// source columns; DTSBindMode_Byref_ProviderOwned is the default, to use a pointer to the
|
||
// provider's data cache and avoid an unnecessary copy.
|
||
//
|
||
// For DBTYPE_BSTR and DBTYPE_VARIANT, this specifies that the binding is DBMEMOWNER_CLIENTOWNED
|
||
// (without BYREF), and the client is responsible for freeing it (e.g. IDTSDataConvert::ClearBindingData).
|
||
//
|
||
DTSBindMode_ClientOwned = 0x00000002,
|
||
|
||
// For Source DBTYPE_((W)STR|BYTES), this flag causes the OLEDB binding to be done as DBTYPE_BYREF
|
||
// with DBMEMOWNER_CLIENTOWNED, resulting in a CoTaskMemAlloc which the client is
|
||
// responsible for freeing (e.g. via IDTSDataConvert::ClearBindingData). For a BLOB
|
||
// column, the length to use for this binding is returned from ValidateSchema() in
|
||
// ppDTSColBinding[ii].cbInMemoryBlobSize. On fetch from Source, the DBSTATUS in the binding
|
||
// will indicate whether the data was truncated; it is up to the Transform server how (or if)
|
||
// this is handled.
|
||
//
|
||
// This flag causes each row to have a separate CoTaskMemAlloc for the source column. This is
|
||
// somewhat less efficient than the other in-memory options, and thus should only be used by
|
||
// a Transform which wants to assume ownership of that allocation. The Transform is responsible
|
||
// for tracking and freeing the allocation (and for ensuring that OnRowComplete does not free
|
||
// it if it is to be used in subsequent Transforms).
|
||
//
|
||
// For destination columns, this is the "safest" way to pass an in-memory pointer, as some providers
|
||
// may not allow ProviderOwned on a destination (such as with Blob columns). The Transform must
|
||
// ensure that it does not double-free a pointer.
|
||
//
|
||
DTSBindMode_Byref_ClientOwned = 0x00000003,
|
||
|
||
// By itself, ProviderOwned is seldom used by itself except for BSTR, which does not always
|
||
// support Byref. It is primarily for DBTYPE_((W)STR|BYTES) with Byref, to reduce allocations
|
||
// and/or copies, as described below. It may not be supported by providers for other datatypes.
|
||
//
|
||
DTSBindMode_ProviderOwned = 0x00000004,
|
||
|
||
// This flag causes source columns to be bound to return a pointer into the provider's memory
|
||
// space for DBTYPE_((W)STR|BYTES). This pointer is read-only and must not be freed.
|
||
//
|
||
// For Blob columns, the Source Provider may not support (Byref_)ProviderOwned Blobs; this
|
||
// would require that the entire Blob be buffered contiguously. Therefore, unless you have
|
||
// specific knowledge of the provider, this flag is discouraged.
|
||
//
|
||
// For DBTYPE_BSTR, the BYREF specification may not be supported, and may require DBMEMOWNER_PROVIDEROWNED
|
||
// (without BYREF). The client must not free the data.
|
||
//
|
||
// For other types, including DBTYPE_VARIANT, OLEDB raises an error for this specification
|
||
// when creating an accessor.
|
||
//
|
||
// For the destination, specifying ProviderOwned requires that the data be shallow-copied into
|
||
// the destination binding to avoid memory leaks (this is automatically done by IDTSDataConvert::
|
||
// ConvertToBinding).
|
||
//
|
||
DTSBindMode_Byref_ProviderOwned = 0x00000005,
|
||
|
||
// This indicates whether the Pump should buffer Source Blob Storage Objects. For most cases,
|
||
// this should be left _BufferDefault; for performance reasons, the DataPump will only buffer
|
||
// where it is necessary to avoid data loss. This is in the following cases:
|
||
// DTSBindMode_Blob_BufferAlways
|
||
// DTSBindMode_Blob_BufferDefault, provider doesn't allow multiple SO's, and any of following:
|
||
// The column is referenced in a subsequent transform.
|
||
// The column is not the rightmost column of all transforms up to and including it.
|
||
//
|
||
// The DataPump can buffer from a source provider's ISequentialStream or ILockBytes, and
|
||
// exposes both these interfaces on its own object. Because it is a buffer, the object's data
|
||
// can be edited via Write(At) to reduce memory requirements in the TransformServer (allowing the
|
||
// source object to be placed in the destination row, if the destination supports Storage Objects).
|
||
//
|
||
// DTSBindMode_Blob_* is ignored for in-memory binding, which is an implicit buffering.
|
||
DTSBindMode_Blob_BufferDefault = 0x00000010,
|
||
DTSBindMode_Blob_BufferAlways = 0x00000020,
|
||
DTSBindMode_Blob_BufferNever = 0x00000040,
|
||
|
||
// This indicates whether to use a Structured Storage object for binding a BLOB column. The Transform
|
||
// Server should indicate which interface it wants in DTSBindInfo::fStorageObject, on return from
|
||
// ValidateSchema(). The DataPump supports the following behaviour:
|
||
// Custom Transformations:
|
||
// For Source, if the DataPump does not buffer, only the provider-supported Storage Object interfaces
|
||
// are available. Generally this will always include ISequentialStream. See comments regarding
|
||
// DTSBindMode_Blob_Buffer*; if the DataPump buffers the Blob data, it supports only ISequentialStream
|
||
// and ILockBytes.
|
||
// If the source does not support storage objects, then the Transform Server must not request a
|
||
// Storage Object, and must bind the source data as in-memory, specifying DTSBindInfo::cbInMemoryBlobSize.
|
||
// For Destination, the Transform Server supplies the Storage object placed into the row, and must
|
||
// specify one interface from fProviderStorageObjects for the DataPump to bind the destination.
|
||
// If the destination does not support storage objects, then the TransformServer must not request
|
||
// a Storage Object, and must bind the destination data as in-memory, ClientOwned or ProviderOwned,
|
||
// specifying DTSBindInfo::cbInMemoryBlobSize.
|
||
// Default (DataPump-supplied) TransformCopy:
|
||
// If either Source or Destination do not support ISequentialStream, then the DataPump will bind both
|
||
// as ClientOwned in-memory, using the source column's DTSBindInfo::cbInMemoryBlobSize.
|
||
// Otherwise, the DataPump will bind to the providers as ISequentialStream, with default buffering.
|
||
// See also comments regarding DTSBindMode_Blob_Buffer*; this can be specified to override the
|
||
// Pump's default handling even in the TransformCopy case.
|
||
//
|
||
// DTSBindMode_Blob_StorageObject cannot be specified with non-DTSBindMode_Blob_* flags.
|
||
DTSBindMode_Blob_StorageObject = 0x00000100,
|
||
} DP_ENUM_END(DTSBindMode);
|
||
|
||
// Indicates which of the DataPump defaults are to be overridden on a single AddTransform().
|
||
typedef DP_ENUM_BEGIN(DTSSpecifyBlobDefaults, "Specify overrides of DataPump Blob-handling defaults") {
|
||
DTSBlobDefault_DataPumpDefaults = 0x0000, // None (initialization)
|
||
DTSBlobDefault_BufferSource = 0x0001, // Override DTSBindMode_Blob_BufferDefault for source Blob Storage Objects
|
||
DTSBlobDefault_InMemorySize = 0x0002, // Override DTS_DEFAULT_INMEMORY_BLOB_SIZE.
|
||
DTSBlobDefault_ForceInMemory = 0x0004, // Force Blobs to be InMemory (no Storage Objects) for this Transform.
|
||
// Forces DTSTransformColumnInfo.fProviderStorageObjects
|
||
// sent to the Transformer to be 0.
|
||
DTSBlobDefault_ForceMultipleStorageObjects = 0x0008, // Forces DTSTransformColumnInfo.dtsProviderFlags sent to the
|
||
// Transformer to include DTSProviderFlag_Blob_MultipleStorageObjects.
|
||
// This could be an optimization if the Source provider supports multiple
|
||
// storage objects and the destination is known to support them only
|
||
// multiple blobs for insert, since the OLEDB spec does not distinguish
|
||
// between multiple-StorageObject support for GetData vs. SetData/Insert.
|
||
} DP_ENUM_END(DTSSpecifyBlobDefaults);
|
||
|
||
// Flags indicating known Provider Blob capabilities; their absence indicates
|
||
// corresponding Provider restrictions or requirements.
|
||
typedef DP_ENUM_BEGIN(DTSProviderFlags, "Provider behaviour characteristics") {
|
||
DTSProviderFlag_None = 0x00000000, // None
|
||
|
||
DTSProviderFlag_ProviderOwned = 0x00000001, // Provider supports Byref binding (some may not).
|
||
|
||
DTSProviderFlag_Blob_InsertNoLength = 0x00000100, // Blob Inserts do not require length to be prespecified
|
||
DTSProviderFlag_Blob_Revisitable = 0x00000200, // Provider guarantees that Blob data is not skipped when succeeding columns fetched
|
||
DTSProviderFlag_Blob_Rewindable = 0x00000400, // Provider guarantees Blob data supports random access
|
||
DTSProviderFlag_Blob_ProviderOwned = 0x00000800, // Provider allows the PROVIDEROWNED flag for use with Blobs
|
||
DTSProviderFlag_Blob_MultipleStorageObjects = 0x00001000, // Provider supports multiple storage objects per row.
|
||
DTSProviderFlag_Blob_NonBlockingStorageObjects = 0x00002000, // Provider supports multiple nonblocking storage objects per row.
|
||
} DP_ENUM_END(DTSProviderFlags);
|
||
|
||
// The actual structure passed to AddTransform to specify overriding Blob defaults.
|
||
// This is most useful for the default TransformCopy case, but can also be used by
|
||
// a client who predetermines (e.g. via a query) the maximum Blob size in the coming
|
||
// result set, for the most efficient memory allocations.
|
||
#ifndef DP_NO_AUTOCTOR
|
||
struct DTSTransformBlobDefaults {
|
||
#else // DP_NO_AUTOCTOR
|
||
typedef struct {
|
||
#endif // DP_NO_AUTOCTOR
|
||
DTSSpecifyBlobDefaults dtsSpecifyMask; // Which of the following items to override.
|
||
BOOL bBufferSource; // If dtsSpecifyMask & DTSBlobDefault_BufferSource;
|
||
// TRUE or FALSE forces Pump to buffer source Blobs or not.
|
||
ULONG cbInMemorySize; // If dtsSpecifyMask & DTSBlobDefault_InMemorySize;
|
||
// overrides DTS_DEFAULT_INMEMORY_BLOB_SIZE. Size in bytes.
|
||
#ifndef DP_NO_AUTOCTOR
|
||
DTSTransformBlobDefaults()
|
||
: dtsSpecifyMask(DTSBlobDefault_DataPumpDefaults)
|
||
{ }
|
||
};
|
||
#else // DP_NO_AUTOCTOR
|
||
} DTSTransformBlobDefaults;
|
||
#endif // DP_NO_AUTOCTOR
|
||
typedef DTSTransformBlobDefaults *LPDTSTransformBlobDefaults;
|
||
typedef const DTSTransformBlobDefaults *LPCDTSTransformBlobDefaults;
|
||
|
||
// Specifies an individual column passed to AddTransform. The column may be specified by
|
||
// name, or if the name is NULL, by an ordinal (this makes unnamed columns easier for the
|
||
// consumer to specify).
|
||
typedef struct {
|
||
LPOLESTR pwzColumnName; // Name of column
|
||
ULONG ulColumnOrdinal; // Ordinal of column if name is NULL; 1-based for OLEDB consistency.
|
||
} DTSTransformColumnSpecification, *LPDTSTransformColumnSpecification;
|
||
typedef const DTSTransformColumnSpecification *LPCDTSTransformColumnSpecification;
|
||
|
||
// Specifies a list of columns passed to AddTransform.
|
||
#ifndef DP_NO_AUTOCTOR
|
||
struct DTSTransformColumnsSpecification {
|
||
#else // DP_NO_AUTOCTOR
|
||
typedef struct {
|
||
#endif // DP_NO_AUTOCTOR
|
||
|
||
ULONG cSourceColumns; // Specify source columns
|
||
LPCDTSTransformColumnSpecification pSourceColumns;
|
||
ULONG cDestinationColumns; // Specify destination columns
|
||
LPCDTSTransformColumnSpecification pDestinationColumns;
|
||
DTSTransformBlobDefaults BlobDefaults; // Blob default overrides if specified
|
||
|
||
#ifndef DP_NO_AUTOCTOR
|
||
DTSTransformColumnsSpecification()
|
||
: cSourceColumns(0)
|
||
, pSourceColumns(NULL)
|
||
, cDestinationColumns(0)
|
||
, pDestinationColumns(NULL)
|
||
{ }
|
||
};
|
||
#else // DP_NO_AUTOCTOR
|
||
} DTSTransformColumnsSpecification;
|
||
#endif // DP_NO_AUTOCTOR
|
||
typedef DTSTransformColumnsSpecification *LPDTSTransformColumnsSpecification;
|
||
typedef const DTSTransformColumnsSpecification *LPCDTSTransformColumnsSpecification;
|
||
|
||
// Specifies a query and list of columns for IDTSDataDrivenQuery.
|
||
#ifndef DP_NO_AUTOCTOR
|
||
struct DTSTransformQuerySpecification {
|
||
#else // DP_NO_AUTOCTOR
|
||
typedef struct {
|
||
#endif // DP_NO_AUTOCTOR
|
||
|
||
LPCOLESTR wzQuery; // The Parameterized Query
|
||
ULONG cColumns; // Specify count of columns
|
||
LPCDTSTransformColumnSpecification pColumns; // Specify column mapping to parameters, in order found in query.
|
||
|
||
#ifndef DP_NO_AUTOCTOR
|
||
DTSTransformQuerySpecification()
|
||
: wzQuery(NULL)
|
||
, cColumns(0)
|
||
, pColumns(NULL)
|
||
{ }
|
||
};
|
||
#else // DP_NO_AUTOCTOR
|
||
} DTSTransformQuerySpecification;
|
||
#endif // DP_NO_AUTOCTOR
|
||
typedef DTSTransformQuerySpecification *LPDTSTransformQuerySpecification;
|
||
typedef const DTSTransformQuerySpecification *LPCDTSTransformQuerySpecification;
|
||
|
||
// Transform-server specifiable binding information. An array of these structures is passed to
|
||
// ValidateSchema() with default values (possibly derived from DTSTransformBlobDefaults overrides),
|
||
// and the Transform Server can set the values. Because source columns can appear multiple times
|
||
// in the same or different transactions, the last specification wins; therefore, a TransformServer's
|
||
// Execute() method should gracefully handle a source binding different from what it specified in
|
||
// ValidateSchema().
|
||
typedef struct {
|
||
DTSBindMode eBindMode; // Per above. For Blobs, specifying a Buffering mode overrides
|
||
// the DataPump and any DTSTransformBlobDefaults default.
|
||
DWORD fStorageObject; // For DTSBindMode_Blob_StorageObject; one of DBPROPVAL_SS_*. If
|
||
// specified, eBindMode must be DTSBindMode_Blob_StorageObject.
|
||
ULONG cbInMemoryBlobSize; // For DTSBindMode of inmemory Blobs. Setting this value overrides
|
||
// the DataPump and any DTSTransformBlobDefaults default. Size in bytes.
|
||
} DTSBindInfo;
|
||
|
||
// This is a single column definition, binding, and data item for DTSTransformColumnInfo.
|
||
typedef struct {
|
||
const DBCOLUMNINFO *pDBColumnInfo; // Pointer to source or destination DBCOLUMNINFO for this column.
|
||
const DBBINDING *pDBBinding; // Pointer to source or destination DBBINDING for this column.
|
||
// wType == DBTYPE_EMPTY if this column is not referenced in any transform.
|
||
DTSBindInfo *pDTSBindInfo; // Pointer to source or destination DTSBindInfo for this column.
|
||
LPBYTE pvData; // Data space for this column, indexed by pDBBinding offsets.
|
||
// NULL if this column was not referenced in any Transform.
|
||
} DTSColumnData;
|
||
|
||
// The DBCOLUMNFLAGS and pwszName are in DBCOLUMNINFO and not DBBINDING;
|
||
// therefore pass both structures to transform code. The COM Transform server uses the
|
||
// binding info to access the pvRowData. This structure is passed to ITransformExecute::
|
||
// Execute to expose the source and destination columns specified by the Transform.
|
||
typedef struct {
|
||
DWORD fProviderStorageObjects; // DBPROPVAL_SS_*; Blob Storage Object interfaces supported
|
||
// by source or destination provider. Will be 0 if none supported,
|
||
// or if DTSTransformBlobDefaults::bForceBlobsInMemory is specified.
|
||
DTSProviderFlags dtsProviderFlags; // Provider characterstics, e.g Blob Flags.
|
||
ULONG cColumns; // Count of columns in rgColumns
|
||
DTSColumnData *rgColumnData; // Column schema and binding information
|
||
ULONG cPriorBlobStorageObjects; // Number of Blobs bound as Storage Objects in prior transforms.
|
||
// Can be used with DTSProviderFlag_Blob_MultipleStorageObjects
|
||
// to determine if the current Transform can use a storage object.
|
||
} DTSTransformColumnInfo, *LPDTSTransformColumnInfo;
|
||
typedef const DTSTransformColumnInfo *LPCDTSTransformColumnInfo;
|
||
|
||
typedef enum {
|
||
DTSGuid_Variant,
|
||
DTSGuid_Guid,
|
||
DTSGuid_OleStr
|
||
} DTSGuidType;
|
||
|
||
typedef struct {
|
||
DTSGuidType eType; // Indexes union.
|
||
union {
|
||
GUID Guid; // GUID form
|
||
VARIANT Variant; // BSTR == progid or clsid (differentiated by looking for <20>.<2E> in name)
|
||
// BYTE/LONG == guid encoding (e.g. Repository))
|
||
// UNKNOWN == pointer to IID_IDTSDataPumpTransform
|
||
LPOLESTR OleStr; // Progid or clsid (differentiated by looking for <20>.<2E> in name)
|
||
} DP_UNION_NAME(u);
|
||
} DTSGuid;
|
||
|
||
#define DTS_DEFAULT_LookupCacheSize 100
|
||
|
||
// Specifies a query and list of columns for IDTSDataDrivenQuery.
|
||
#ifndef DP_NO_AUTOCTOR
|
||
struct DTSTransformLookupSpecification {
|
||
#else // DP_NO_AUTOCTOR
|
||
typedef struct {
|
||
#endif // DP_NO_AUTOCTOR
|
||
|
||
LPCOLESTR wzName; // Name of the Lookup (for disambiguation)
|
||
LPCOLESTR wzQuery; // The Parameterized Query
|
||
IUnknown *pIUnkSession; // Session to use for the Lookup
|
||
ULONG cMaxCacheRows; // Number of rows to cache
|
||
|
||
#ifndef DP_NO_AUTOCTOR
|
||
DTSTransformLookupSpecification()
|
||
: wzName(NULL)
|
||
, wzQuery(NULL)
|
||
, pIUnkSession(NULL)
|
||
, cMaxCacheRows(DTS_DEFAULT_LookupCacheSize)
|
||
{ }
|
||
};
|
||
#else // DP_NO_AUTOCTOR
|
||
} DTSTransformLookupSpecification;
|
||
#endif // DP_NO_AUTOCTOR
|
||
typedef DTSTransformLookupSpecification *LPDTSTransformLookupSpecification;
|
||
typedef const DTSTransformLookupSpecification *LPCDTSTransformLookupSpecification;
|
||
|
||
///////////////////////////////////////////////////////////////////////////////////////
|
||
// Class and IID definitions
|
||
///////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
// Forward-define all interfaces.
|
||
#define DP_FWD_DEFINE_INTERFACE(itf) \
|
||
interface itf; \
|
||
typedef interface itf * LP##itf;
|
||
|
||
// Repeat the IUnknown and IDispatch members because C doesn't provide inheritance.
|
||
#ifndef DTSDataPump_Unknown_Base
|
||
#define DTSDataPump_Unknown_Base() \
|
||
STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; \
|
||
STDMETHOD_(ULONG,AddRef) (THIS) PURE; \
|
||
STDMETHOD_(ULONG,Release) (THIS) PURE;
|
||
#endif
|
||
#ifndef DTSDataPump_Dispatch_Base
|
||
#define DTSDataPump_Dispatch_Base(itf) \
|
||
DTSDataPump_Unknown_Base() \
|
||
STDMETHOD(GetTypeInfoCount)(UINT FAR* pcTypeInfo) PURE; \
|
||
STDMETHOD(GetTypeInfo)(UINT iTypeInfo, LCID lcid, ITypeInfo FAR* FAR* ppTI) PURE; \
|
||
STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR FAR* rgszNames, UINT cNames, \
|
||
LCID lcid, DISPID FAR* rgdispid) PURE; \
|
||
STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, \
|
||
DISPPARAMS FAR* pdispparams, LPVARIANT pvarResult, \
|
||
LPEXCEPINFO pexcepinfo, UINT FAR* puArgErr) PURE;
|
||
#endif
|
||
#ifndef DTSDataPump_IDispatch
|
||
#define DTSDataPump_IDispatch IDispatch
|
||
#endif
|
||
|
||
// Include <initguid.h> to define ownership of these GUIDs.
|
||
// {xxxxxxxx-740b-11d0-ae7b-00aa004a34d5}
|
||
#define DEFINE_DTSDataPumpGUID(name, lval) \
|
||
DEFINE_GUID(name, 0x##lval, 0x740b, 0x11d0, 0xae, 0x7b, 0x0, 0xaa, 0x0, 0x4a, 0x34, 0xd5);
|
||
|
||
// DTSPump-supplied classes and interfaces.
|
||
DP_FWD_DEFINE_INTERFACE(IDTSDataPump)
|
||
#define Progid_DTSDataPump OLESTR("DTS.DataPump")
|
||
DEFINE_DTSDataPumpGUID(CLSID_DTSDataPump, 10010100)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataPump, 10010101)
|
||
|
||
#define Progid_DTSErrorLookup OLESTR("DTS.ErrorLookup")
|
||
DEFINE_DTSDataPumpGUID(CLSID_DTSErrorLookup, 10010102)
|
||
|
||
DP_FWD_DEFINE_INTERFACE(IDTSDataConvert)
|
||
#define Progid_DTSDataConvert OLESTR("DTS.DataConvert")
|
||
DEFINE_DTSDataPumpGUID(CLSID_DTSDataConvert, 10010103)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataConvert, 10010104)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataDrivenQuery, 10010105)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataPumpSpecifyLookups, 10010106)
|
||
|
||
// DTS Typelib IID's.
|
||
DEFINE_DTSDataPumpGUID(LIBID_DataPump, 10010200)
|
||
DP_FWD_DEFINE_INTERFACE(IDTSDataPumpColumns)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataPumpColumns, 10010201)
|
||
DP_FWD_DEFINE_INTERFACE(IDTSDataPumpColumn)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataPumpColumn, 10010202)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSErrorRecords, 10010203)
|
||
DP_FWD_DEFINE_INTERFACE(IDTSDataPumpLookups)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataPumpLookups, 10010204)
|
||
DP_FWD_DEFINE_INTERFACE(IDTSDataPumpLookup)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataPumpLookup, 10010205)
|
||
DP_FWD_DEFINE_INTERFACE(IDTSDataPumpLookupVariant)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataPumpLookupVariant, 10010206)
|
||
|
||
// Repository Storage IIDs.
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSRepositoryProvider, 100202F1)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSRepositoryStorage, 100202F2)
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////
|
||
// Category id of DTS custom transforms.
|
||
/////////////////////////////////////////////////////////////////////////////////
|
||
DEFINE_DTSDataPumpGUID(CATID_DTSCustomXform, 10010100) //we will use the same id as the pump clsid.
|
||
|
||
// Consumer-supplied classes and interfaces.
|
||
DP_FWD_DEFINE_INTERFACE(IDTSDataPumpTransform)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataPumpTransform, 10010300)
|
||
|
||
DP_FWD_DEFINE_INTERFACE(IDTSDataPumpErrorSink)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataPumpErrorSink, 10010301)
|
||
|
||
DP_FWD_DEFINE_INTERFACE(IDTSDataPumpProgressSink)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataPumpProgressSink, 10010302)
|
||
|
||
DP_FWD_DEFINE_INTERFACE(IDTSDataDrivenQuerySink)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataDrivenQuerySink, 10010303)
|
||
|
||
// DTSDataPump-supplied COM Transform Servers
|
||
// A "Transformation Server" coclass consists of:
|
||
// coclass TTransformServer {
|
||
// required IDTSDataPumpTransform;
|
||
//
|
||
// // The following are optional if the TransformServer has no custom
|
||
// // properties requiring editing. If it has, these are required.
|
||
// optional <Custom OleAut properties interface>;
|
||
// optional ISpecifyPropertyPages;
|
||
// optional IPropertyPage;
|
||
// optional IPersistPropertyBag;
|
||
// }
|
||
|
||
#define Progid_DTSDataPumpTransformCopy OLESTR("DTS.DataPumpTransformCopy")
|
||
DEFINE_DTSDataPumpGUID(CLSID_DTSDataPumpTransformCopy, 10010400)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataPumpTransformCopy, 10010401)
|
||
// No custom properties, therefore no custom interface or IID.
|
||
|
||
#define Progid_DTSDataPumpTransformScript OLESTR("DTS.DataPumpTransformScript")
|
||
DEFINE_DTSDataPumpGUID(CLSID_DTSDataPumpTransformScript, 10010501);
|
||
DP_FWD_DEFINE_INTERFACE(IDTSDataPumpTransformScriptProperties)
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataPumpTransformScriptProperties, 10010502);
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSDataPumpTransformScript, 10010503);
|
||
|
||
//optional interface to be implemented by custom transform providers - used by DTS UI to configure the transforms
|
||
DEFINE_DTSDataPumpGUID(IID_IDTSCustomTransformUI, 10010601);
|
||
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// DataPump-supplied Transform variables.
|
||
//
|
||
// These are passed to IDTSDataPumpTransform::AddVariable. They are all of type
|
||
// VT_VARIANT. IDTSErrorRecords (interface defined below) allows any transform
|
||
// to append OLEDB Error Records to IErrorInfo for the current thread. The name
|
||
// "DTSErrorRecords" is what is passed to IDTSDataPumpTransform::AddVariable; the
|
||
// VT_DISPATCH ma be QI'd (or cast) to IDTSErrorRecords. This object is also
|
||
// inserted into ActiveX Scripting namespaces invoked by the Pump. All DTS-generated
|
||
// variables are inserted into ActiveX scripting namespaces as non-global variables
|
||
// (i.e. their methods must be qualified with the object name).
|
||
//
|
||
// Name Type
|
||
// ---- ----
|
||
// DTSError DTS.Error
|
||
#define wzDTSErrorRecords OLESTR("DTSErrorRecords")
|
||
|
||
//
|
||
// These are inserted by name into the global namespace of an ActiveX scripting transform.
|
||
// View the type library to see the type definitions. Note that the return value from the
|
||
// method (FunctionEntry) must be an integral type.
|
||
//
|
||
// Name Type
|
||
// ---- ----
|
||
// DTSSource DTS.Columns
|
||
// DTSDestination DTS.Columns
|
||
// (return value) adInt or adSmallInt (DTSTransformStatus)
|
||
//
|
||
|
||
//
|
||
// These are inserted by name into the global namespace of an ActiveX scripting transform,
|
||
// as well as being passed to IDTSDataPumpTransform::AddVariable.
|
||
//
|
||
// Name Type
|
||
// ---- ----
|
||
// DTSLookups DTS.Lookups
|
||
#define wzDTSLookups OLESTR("DTSLookups")
|
||
|
||
// These are the DTS-Package-supplied global variables, if the Pump is being run from
|
||
// the Package.
|
||
#define wzDTSGlobalVariables OLESTR("DTSGlobalVariables")
|
||
|
||
// These are special pseudo-columnnames corresponding to Lineage. They are also
|
||
// the names of the corresponding GlobalVariables; TransformCopy will automatically
|
||
// map them over to the specified destination column. These names must not be used
|
||
// by source column names.
|
||
#define wzDTSLineage_FullString OLESTR("DTSLineage_Full")
|
||
#define wzDTSLineage_IntegerCRC OLESTR("DTSLineage_Short")
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// DataPump-supplied interface definitions.
|
||
//
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
///////////////////////////////////////
|
||
// IDTSDataPump - Primary interface to specify source and destination rowsets,
|
||
// add Transforms, and Execute() the transfer. AddTransform will error if
|
||
// SetRowsets has not been called, and SetRowsets will error if any transforms
|
||
// have been added (because ValidateSchema has been done on them already).
|
||
// InitNew() reinitializes the IDTSDataPump object. Execute returns E_FAIL if aborted,
|
||
// DB_E_ERRORSOCCURRED if max error count exceeded; DB_S_ERRORSOCCURRED if errors
|
||
// less than the max allowed occurred, possible provider-specific errors, or NOERROR
|
||
// if completed with no errors.
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataPump
|
||
DECLARE_INTERFACE_(IDTSDataPump, IUnknown)
|
||
{
|
||
DTSDataPump_Unknown_Base()
|
||
|
||
STDMETHOD(InitNew)(THIS) PURE;
|
||
STDMETHOD(GetRowsets)(THIS_
|
||
DP_OUT IRowset **ppSrcRowset,
|
||
DP_OUT IRowsetChange **ppDestRowsetChange
|
||
) PURE;
|
||
STDMETHOD(SetRowsets)(THIS_
|
||
DP_IN IRowset *pSrcRowset, // Must be able to retrieve these rows
|
||
DP_IN IRowsetChange *pDestRowsetChange // Must have DBPROP_UPDATABILITY: DPBROP_UP_INSERT
|
||
) PURE;
|
||
STDMETHOD(SetProgressRowCount)(THIS_
|
||
DP_IN ULONG cIn // Interval for IDTSDataPumpProgressSink::OnIntervalComplete; default == 1000
|
||
) PURE;
|
||
STDMETHOD(SetMaximumErrorRowCount)(THIS_
|
||
DP_IN ULONG cIn // Maximum allowable error rows; default = 0 (abort on first error row).
|
||
) PURE;
|
||
STDMETHOD(SetFetchBufferSize)(THIS_
|
||
DP_IN ULONG cIn // Size of the GetNextRows HROW buffer (default = 1)
|
||
) PURE;
|
||
STDMETHOD(SetInsertCommitSize)(THIS_
|
||
DP_IN ULONG cIn // Number of successful InsertRows between "Commits", if supported by provider (default == 0; all rows in one batch).
|
||
) PURE;
|
||
STDMETHOD(AddTransform)(THIS_
|
||
DP_IN LPCOLESTR pwzName, // Transform name
|
||
DP_IN LPBYTE pvUserData, // Will be passed to Sink if event occurs on Transform.
|
||
DP_IN LPCDTSTransformColumnsSpecification pColumns, // Source and destination columns
|
||
DP_IN DTSGuid ServerClsid, // COM server ProgID or CLSID or IUnknown
|
||
DP_IN VARIANT ServerParameters, // Parameters to server for this transform
|
||
DP_IN DTSTransformFlags dwFlags, // Transformation column-validation flags
|
||
DP_IN IStorage *pIStorage // Pointer to persistent storage of Transform properties
|
||
) PURE;
|
||
STDMETHOD(AddTransformVariable)(THIS_
|
||
DP_IN LPCOLESTR pwzName, // Variable name
|
||
DP_IN BOOL bGlobal, // For ActiveX scripts, indicates whether this variable's
|
||
// methods must be qualified by the object name.
|
||
DP_IN VARIANT Variable // Variable value; passed to and updatable by Transform
|
||
) PURE;
|
||
STDMETHOD(Execute)(THIS_
|
||
DP_IN LPBYTE pvUserData, // User data passed back to Sinks.
|
||
DP_OUT ULARGE_INTEGER *puliRowsComplete, // Total number of source rows processed (including those skipped).
|
||
DP_OUT ULONG *pulErrorRows, // Total number of error rows encountered.
|
||
DP_OUT LPDTSExecuteStatus pExecStatus // Pump return status.
|
||
) PURE;
|
||
STDMETHOD(SetFirstRow)(THIS_
|
||
DP_IN ULARGE_INTEGER cIn // First source row to copy. Default is 1 (first row).
|
||
) PURE;
|
||
STDMETHOD(SetLastRow)(THIS_
|
||
DP_IN ULARGE_INTEGER cIn // Last source row to copy. Default is 0 (copy all rows).
|
||
) PURE;
|
||
};
|
||
|
||
///////////////////////////////////////
|
||
// IDTSDataDrivenQuery - Allows specification of individual queries instead
|
||
// of simple Insert at the Destination. QI'd from IDTSDataPump.
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataDrivenQuery
|
||
DECLARE_INTERFACE_(IDTSDataDrivenQuery, IUnknown)
|
||
{
|
||
DTSDataPump_Unknown_Base()
|
||
|
||
// The following four pairs of properties and methods should be called in the
|
||
// order listed.
|
||
|
||
// Specify and retrieve the source rowset from which data will be read.
|
||
STDMETHOD(SetSourceRowset)(THIS_
|
||
DP_IN IRowset *pSrcRowset
|
||
) PURE;
|
||
STDMETHOD(GetSourceRowset)(THIS_
|
||
DP_OUT IRowset **ppSrcRowset
|
||
) PURE;
|
||
|
||
// Specify and retrieve the destination session and column schema; this defines how the
|
||
// parameters to the queries will be bound. Specifying the schema is done in one of two ways:
|
||
// - If cColumnDescs is 0, then rgColumnDescs is ignored and pDestConnection must
|
||
// be a Rowset. Rowset information will be retrieved, but the Rowset itself will not
|
||
// be retained. The Session will be retrieved from the Rowset and retained.
|
||
// - If cColumnDescs is not 0, then rgColumnDescs must not be NULL and pDestConnection
|
||
// must be a Session. The destination column definitions are created from the DBCOLUMNDESCs.
|
||
//
|
||
STDMETHOD(SetDestinationInfo)(THIS_
|
||
DP_IN IUnknown *pDestConnection,
|
||
DP_IN ULONG cColumnDescs,
|
||
DP_IN DBCOLUMNDESC rgColumnDescs[]
|
||
) PURE;
|
||
// pcColumns, prgInfo, and ppStringsBuffer are allocated as in IColumnsInfo::GetColumnInfo.
|
||
STDMETHOD(GetDestinationInfo)(THIS_
|
||
DP_IN REFIID riidSession,
|
||
DP_OUT IUnknown **ppIUnkSession,
|
||
DP_OUT ULONG *pcColumns,
|
||
DP_OUT DBCOLUMNINFO **prgInfo,
|
||
DP_OUT OLECHAR **ppStringsBuffer
|
||
) PURE;
|
||
|
||
// Specify and retrieve the destination queries and their column mappings to parameters.
|
||
// Unused queries may be NULL, in which case a Transform return status of DTSTransformStat_*Query
|
||
// indicating an unset query will result in an error.
|
||
STDMETHOD(SetDestinationQueries)(THIS_
|
||
DP_IN LPCDTSTransformQuerySpecification pInsertQuerySpec,
|
||
DP_IN LPCDTSTransformQuerySpecification pUpdateQuerySpec,
|
||
DP_IN LPCDTSTransformQuerySpecification pDeleteQuerySpec,
|
||
DP_IN LPCDTSTransformQuerySpecification pUserQuerySpec
|
||
) PURE;
|
||
// Each pointer is a single CoTaskMemAlloc containing space for the base QuerySpecification structure,
|
||
// the array of column info, and the string buffer. Internal pointers are based (with alignment)
|
||
// according to this allocated space.
|
||
STDMETHOD(GetDestinationQueries)(THIS_
|
||
DP_OUT LPDTSTransformQuerySpecification *ppInsertQuerySpec,
|
||
DP_OUT LPDTSTransformQuerySpecification *ppUpdateQuerySpec,
|
||
DP_OUT LPDTSTransformQuerySpecification *ppDeleteQuerySpec,
|
||
DP_OUT LPDTSTransformQuerySpecification *ppUserQuerySpec
|
||
) PURE;
|
||
};
|
||
|
||
///////////////////////////////////////
|
||
// IDTSDataPumpLookups - Allows specification of Lookups for TransformServer use.
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataPumpSpecifyLookups
|
||
DECLARE_INTERFACE_(IDTSDataPumpSpecifyLookups, IUnknown)
|
||
{
|
||
DTSDataPump_Unknown_Base()
|
||
|
||
// Specify and retrieve the lookup specifications for this DataPump instance.
|
||
STDMETHOD(SetLookups)(THIS_
|
||
DP_IN ULONG cLookups,
|
||
DP_IN LPCDTSTransformLookupSpecification pLookups
|
||
) PURE;
|
||
// The pointer is a single CoTaskMemAlloc containing space for the base LookupSpecification structure
|
||
// and the string buffer. Internal pointers are based (with alignment) according to this allocated space.
|
||
// pIUnkSession is AddRef'd and must be released.
|
||
STDMETHOD(GetLookups)(THIS_
|
||
DP_IN ULONG *pcLookups,
|
||
DP_IN LPDTSTransformLookupSpecification *ppLookups
|
||
) PURE;
|
||
};
|
||
|
||
///////////////////////////////////////
|
||
// IDTSDataConvert - The DTS data-conversion interface.
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataConvert
|
||
DECLARE_INTERFACE_(IDTSDataConvert, IDataConvert)
|
||
{
|
||
DTSDataPump_Unknown_Base()
|
||
|
||
//////////////////////////////////////////////////////
|
||
// IDataConvert interface members (msdadc.h required).
|
||
//////////////////////////////////////////////////////
|
||
|
||
// Copies or converts data from one DBTYPE to another. If wDstType includes DBTYPE_BYREF,
|
||
// it must be a variable-length type (DBTYPE_((W)STR|BYTES)) or this method will error.
|
||
// Otherwise, for all DBTYPE_BYREF destination conversions, this method CoTaskMemAlloc(s)
|
||
// the destination data pointer, and it is the caller's responsibility to CoTaskMemFree it.
|
||
// This method should not be used to place data into the DataPump's destination binding;
|
||
// instead, use the ConvertToBinding method.
|
||
STDMETHOD(DataConvert)(
|
||
DP_IN DBTYPE wSrcType,
|
||
DP_IN DBTYPE wDstType,
|
||
DP_IN ULONG cbSrcLength,
|
||
DP_INOUT ULONG *pcbDstLength,
|
||
DP_IN void *pSrc,
|
||
DP_OUT void *pDst,
|
||
DP_IN ULONG cbDstMaxLength,
|
||
DP_IN DBSTATUS dbsSrcStatus,
|
||
DP_OUT DBSTATUS *pdbsStatus,
|
||
DP_IN BYTE bPrecision,
|
||
DP_IN BYTE bScale,
|
||
DP_IN DBDATACONVERT dwFlags
|
||
) PURE;
|
||
|
||
// Determines if two types are potentially compatible. See GetConvertFlags
|
||
// for more detailed information about what the conversion may encounter.
|
||
STDMETHOD(CanConvert)(
|
||
DP_IN DBTYPE wSrcType,
|
||
DP_IN DBTYPE wDstType
|
||
) PURE;
|
||
|
||
// Returns the required conversion size in bytes. May base this on pcbSrcLength
|
||
// and/or pSrc, if supplied, to get per-data-item information.
|
||
//
|
||
// DBTYPE_BSTR is considered a fixed type; its binding length is sizeof(BSTR).
|
||
// To determine the length necessary to pre-allocate a BSTR, pass in DBTYPE_STR
|
||
// for the destination type - for this type, character count == byte count.
|
||
// Alternatively, use WSTR and divide the return by sizeof(WCHAR).
|
||
//
|
||
STDMETHOD(GetConversionSize)(
|
||
DP_IN DBTYPE wSrcType,
|
||
DP_IN DBTYPE wDstType,
|
||
DP_IN ULONG *pcbSrcLength,
|
||
DP_OUT ULONG *pcbDstLength,
|
||
DP_IN void *pSrc
|
||
) PURE;
|
||
|
||
//////////////////////////////////////////////////////
|
||
// DTS extensions.
|
||
//////////////////////////////////////////////////////
|
||
|
||
// This method first calls CanConvert() to determine if the conversion can succeed at all
|
||
// given the source and destination datatypes, and if so, returns extended information about
|
||
// how (or if) the conversion can proceed after that.
|
||
// It uses the following fields for source and destination (S and D):
|
||
// DBCOLUMNINFO - validates all conversion info between columns.
|
||
// dwFlags S,D
|
||
// ulColumnSize S,D
|
||
// wType S,D
|
||
// bPrecision S,D
|
||
// bScale S,D
|
||
// Fields other than dwFlags and wType can be zero'd and the output ConvertFlags
|
||
// tested for the Unsupported bit if length validation is not required.
|
||
// Note that this does not set a flag for nontext <-> text if the text length is
|
||
// sufficient to accommodate it; this is because all such conversions should be valid
|
||
// If this level of exactness is required, simply compare the datatypes for equality.
|
||
STDMETHOD(GetConvertFlags)(
|
||
DP_IN const DBCOLUMNINFO *pSrcColumnInfo, // Source column metadata
|
||
DP_IN const DBCOLUMNINFO *pDestColumnInfo, // Destination column metadata
|
||
DP_OUT DTSConvertFlags *pConvertFlags // Output conversion flags
|
||
) PURE;
|
||
|
||
// This method allows the Transform Server to convert source data (which may come from
|
||
// the source binding directly, as in the comment examples, or from ad-hoc source data).
|
||
// It uses the following fields in the destination binding (S is fields that are used
|
||
// from a source binding if that is how the source data is stored):
|
||
// DBBINDING:
|
||
// obValue S,D -- must be bound
|
||
// obLength S,D -- must be bound
|
||
// obStatus S,D -- must be bound
|
||
// dwPart S,D -- must include length, value, status
|
||
// cbMaxLen D
|
||
// wType S,D
|
||
// bPrecision D
|
||
// bScale D
|
||
//
|
||
// The destination data is set according to eTransformFlags and pDestBind->dwMemOwner, which
|
||
// is handled as follows:
|
||
//
|
||
// DBMEMOWNER_CLIENTOWNED: normal conversion is done; data is copied from source to destination,
|
||
// converted as needed, and allocations are done as needed. Specifically:
|
||
// BSTR data is deep-copied
|
||
// BYREF destination data is copied into a CoTaskMemAlloc()'d pointer.
|
||
// IUnknown and IDispatch pointers are AddRef()'d.
|
||
// The destination binding data must always be free'd. The foregoing lists what is freed
|
||
// (or Release()'d) by IDTSDataConvert::ClearBindingData.
|
||
//
|
||
// DBMEMOWNER_PROVIDEROWNED: Conversion will attempt to shallow-copy data, avoiding allocations.
|
||
// This requires that the source and destination datatypes be identical (except for DBTYPE_BYREF).
|
||
// This is intended as a performance enhancement and requires that the source data remain stable
|
||
// for the lifetime of the Destination binding (such as while being inserted via the DataPump).
|
||
// It handles only the following cases:
|
||
// If the destination type includes DBTYPE_BYREF // it must therefore be ((W)STR|BYTES)
|
||
// *pvDestData = pvSrcData (or *pvSrcData if source type is BYREF)
|
||
// StringTruncation is performed by adjusting destination datalength
|
||
// else if destination type is BSTR
|
||
// *pvDestData = *pvSrcData (or **pvSrcData if source type is BYREF)
|
||
// StringTruncation is NOT checked here as this is a fixed-length datatype
|
||
// else
|
||
// Normal conversion is done, including:
|
||
// AddRefs of IDispatch/IUnknown pointers
|
||
// VariantCopy (OLEDB behaviour does not allow PROVIDEROWNED Variant binding).
|
||
// DBMEMOWNER_PROVIDEROWNED binding data will not be freed by IDTSDataConvert::ClearBindingData.
|
||
// If a custom allocator is used for BYREF destination data, then it must be freed by a corresponding
|
||
// custom deallocator, rather than by ClearBindingData. Therefore, it should be bound ProviderOwned;
|
||
// the pointer will be shallow-copied into the binding by IDTSDataConvert::ConvertToBinding.
|
||
//
|
||
STDMETHOD(ConvertToBinding)(
|
||
DP_IN DBTYPE wSrcType, // Source datatype: e.g. pSrcBind->wType
|
||
DP_IN ULONG cbSrcLength, // Source data length: e.g. *(reinterpret_cast<ULONG *>(pSrcColumnInfo->pvRowData + pSrcBind->obLength));
|
||
DP_IN DBSTATUS dbsSrcStatus, // Source data status: e.g. *(reinterpret_cast<DBSTATUS *>(pSrcColumnInfo->pvRowData + pSrcBind->obStatus));
|
||
DP_IN const BYTE *pvSrcColData, // Source column data: e.g. pSrcColumnInfo->pvRowData + pSrcBind->obValue;
|
||
DP_IN const DBBINDING *pDestBind, // Dest binding info
|
||
DP_IN BYTE *pvDestRowData, // Dest row data; NOT obValue-offset as the Binding will reference it 3 ways (obLength, obValue, obStatus)
|
||
DP_IN DBCOLUMNFLAGS dwDestColumnFlags, // Dest flags such as nullability
|
||
DP_IN ULONG ulDestColumnSize, // If nonzero and Dest is BYREF, tested for String Truncation
|
||
DP_IN DTSTransformFlags eTransformFlags // Transformation flags. Currently considered:
|
||
// DTSTransformFlag_AllowStringTruncation
|
||
// DTSTransformFlag_ForceConvert as it applies to foregoing
|
||
) PURE;
|
||
|
||
// This method frees any CLIENTOWNED allocations in the Binding, as discussed in ConvertToBinding.
|
||
// This method always sets length to 0 and status to DBSTATUS_S_ISNULL, and can zeroinit if specified.
|
||
STDMETHOD(ClearBindingData)(
|
||
DP_IN const DBBINDING *pDestBind, // Dest binding info
|
||
DP_IN BYTE *pvDestRowData, // Dest row data; NOT obValue-offset as the Binding will reference it 3 ways (obLength, obValue, obStatus)
|
||
DP_IN BOOL bZeroInit // If TRUE, zero's the data value
|
||
) PURE;
|
||
};
|
||
|
||
///////////////////////////////////////
|
||
// IDTSErrorRecords - Allows the caller to append OLEDB Error Records to the current
|
||
// thread's IErrorInfo. The Error Lookup Service is CLSID_DTSErrorLookup.
|
||
// This interface is derived from IDispatch and may be used in ActiveX Scripts as
|
||
// well as from C/C++.
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSErrorRecords
|
||
DECLARE_INTERFACE_(IDTSErrorRecords, DTSDataPump_IDispatch)
|
||
{
|
||
DTSDataPump_Dispatch_Base(IDTSErrorRecords)
|
||
|
||
STDMETHOD(Clear)(THIS) PURE;
|
||
STDMETHOD(Add)(THIS_ DP_IN long Number,
|
||
DP_IN long NativeError,
|
||
DP_IN BSTR Description,
|
||
DP_IN BSTR Source,
|
||
DP_IN BSTR Helpfile,
|
||
DP_IN long Helpid
|
||
) PURE;
|
||
};
|
||
|
||
///////////////////////////////////////
|
||
// IDTSDataPumpColumns - Columns collection as exposed to AxScript.
|
||
// We expose DTSSource and DTSDestination collections.
|
||
// This interface is derived from IDispatch and may be used in ActiveX Scripts as
|
||
// well as from C/C++. This is identical to the ADO.Field interface.
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataPumpColumns
|
||
DECLARE_INTERFACE_(IDTSDataPumpColumns, DTSDataPump_IDispatch)
|
||
{
|
||
DTSDataPump_Dispatch_Base(IDTSDataPumpColumns)
|
||
|
||
STDMETHOD(Item)(THIS_ DP_IN VARIANT Index, DP_OUT IDTSDataPumpColumn **pRetVal) PURE;
|
||
STDMETHOD(get__NewEnum)(THIS_ DP_OUT IUnknown **ppEnum) PURE;
|
||
STDMETHOD(get_Count)(THIS_ DP_OUT long *pRetVal) PURE;
|
||
};
|
||
|
||
///////////////////////////////////////
|
||
// IDTSDataPumpColumn - Column object as exposed to AxScript.
|
||
// These objects make up the DTSSource and DTSDestination collections.
|
||
// They provide access to the column value and its metadata
|
||
// This interface is derived from IDispatch and may be used in ActiveX Scripts as
|
||
// well as from C/C++. This is identical to the ADO.Field interface.
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataPumpColumn
|
||
DECLARE_INTERFACE_(IDTSDataPumpColumn, DTSDataPump_IDispatch)
|
||
{
|
||
DTSDataPump_Dispatch_Base(IDTSDataPumpColumn)
|
||
|
||
STDMETHOD(get_Value)(THIS_ DP_OUT VARIANT *pRetVal) PURE;
|
||
STDMETHOD(put_Value)(THIS_ DP_IN VARIANT NewValue) PURE;
|
||
STDMETHOD(get_ActualSize)(THIS_ DP_OUT long *pl) PURE;
|
||
STDMETHOD(get_Attributes)(THIS_ DP_OUT long *pl) PURE;
|
||
STDMETHOD(get_DefinedSize)(THIS_ DP_OUT long *pl) PURE;
|
||
STDMETHOD(get_Name)(THIS_ DP_OUT BSTR *pbstr) PURE;
|
||
STDMETHOD(get_Type)(THIS_ DP_OUT long *pDataType) PURE;
|
||
STDMETHOD(get_Precision)(THIS_ DP_OUT BYTE *pbPrecision) PURE;
|
||
STDMETHOD(get_NumericScale)(THIS_ DP_OUT BYTE *pbNumericScale) PURE;
|
||
STDMETHOD(get_OriginalValue)(THIS_ DP_OUT VARIANT *pvar) PURE;
|
||
STDMETHOD(get_UnderlyingValue)(THIS_ DP_OUT VARIANT *pvar) PURE;
|
||
STDMETHOD(AppendChunk)(THIS_ DP_IN VARIANT Data) PURE;
|
||
STDMETHOD(GetChunk)(THIS_ DP_IN long Length, DP_OUT VARIANT *pvar) PURE;
|
||
};
|
||
|
||
///////////////////////////////////////
|
||
// IDTSDataPumpLookups - Lookups collection as exposed to AxScript.
|
||
// We expose DTSLookups as a collection.
|
||
// This interface is derived from IDispatch and may be used in ActiveX Scripts as
|
||
// well as from C/C++.
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataPumpLookups
|
||
DECLARE_INTERFACE_(IDTSDataPumpLookups, DTSDataPump_IDispatch)
|
||
{
|
||
DTSDataPump_Dispatch_Base(IDTSDataPumpLookups)
|
||
|
||
STDMETHOD(Item)(THIS_ DP_IN VARIANT Index, DP_OUT IDTSDataPumpLookup **pRetVal) PURE;
|
||
STDMETHOD(Get_NewEnum)(THIS_ DP_OUT IUnknown **ppEnum) PURE;
|
||
STDMETHOD(GetCount)(THIS_ DP_OUT long *pRetVal) PURE;
|
||
};
|
||
|
||
///////////////////////////////////////
|
||
// IDTSDataPumpLookup - Lookup object as exposed to AxScript.
|
||
// These objects make up the DTSLookups collection.
|
||
// This interface is derived from IDispatch and may be used in ActiveX Scripts as
|
||
// well as from C/C++. The KeyValues input parameter to the methods is a SafeArray
|
||
// of Variant, using the vararg attribute on the methods, for best use in ActiveX
|
||
// scripts. The return value is a variant (if single-valued) or an array of variants
|
||
// (if multi-valued) corresponding to the sequence of columns in the single output
|
||
// row resulting from execution of the query. If multiple rows are returned, only
|
||
// the first is returned in the output variant. LastRowCount is used in case an
|
||
// app wants to assert that only one row was returned.
|
||
///////////////////////////////////////
|
||
|
||
// This form is understood by scripting languages to take a variable number of
|
||
// arguments in the key values specification. It can be used from C++ as well.
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataPumpLookup
|
||
DECLARE_INTERFACE_(IDTSDataPumpLookup, DTSDataPump_IDispatch)
|
||
{
|
||
DTSDataPump_Dispatch_Base(IDTSDataPumpLookup)
|
||
|
||
STDMETHOD(get_Name)(THIS_ DP_OUT BSTR *pbstr) PURE;
|
||
STDMETHOD(get_LastRowCount)(THIS_ LONG *pRetVal) PURE;
|
||
STDMETHOD(Execute)(THIS_ DP_IN SAFEARRAY * KeyValues, DP_OUT VARIANT *pRetVal) PURE;
|
||
STDMETHOD(AddToCache)(THIS_ DP_IN VARIANT DataValues, DP_IN SAFEARRAY * KeyValues) PURE;
|
||
STDMETHOD(RemoveFromCache)(THIS_ DP_IN SAFEARRAY * KeyValues) PURE;
|
||
};
|
||
|
||
// This is a form of the interface which takes a single Variant, more convenient
|
||
// for C++ programs which know they'll only have a single key column. The variant
|
||
// may be a single value or may itself contain a safearray.
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataPumpLookupVariant
|
||
DECLARE_INTERFACE_(IDTSDataPumpLookupVariant, IUnknown)
|
||
{
|
||
STDMETHOD(Execute)(THIS_ DP_IN VARIANT KeyValues, DP_OUT VARIANT *pRetVal) PURE;
|
||
STDMETHOD(AddToCache)(THIS_ DP_IN VARIANT DataValues, DP_IN VARIANT KeyValues) PURE;
|
||
STDMETHOD(RemoveFromCache)(THIS_ DP_IN VARIANT KeyValues) PURE;
|
||
};
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// Pump-supplied Transform custom-property interfaces.
|
||
//
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
///////////////////////////////////////
|
||
// IDTSDataPumpTransformScriptProperties - Sets custom properties for the
|
||
// ActiveX scripting transformation server.
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataPumpTransformScriptProperties
|
||
DECLARE_INTERFACE_(IDTSDataPumpTransformScriptProperties, DTSDataPump_IDispatch)
|
||
{
|
||
DTSDataPump_Dispatch_Base(IDTSDataPumpTransformScriptProperties)
|
||
|
||
STDMETHOD(GetText)(THIS_ BSTR DP_OUT *pRetVal) PURE;
|
||
STDMETHOD(SetText)(THIS_ BSTR DP_IN NewValue) PURE;
|
||
STDMETHOD(GetLanguage)(THIS_ BSTR DP_OUT *pRetVal) PURE;
|
||
STDMETHOD(SetLanguage)(THIS_ BSTR DP_IN NewValue) PURE;
|
||
STDMETHOD(GetFunctionEntry)(THIS_ BSTR DP_OUT *pRetVal) PURE;
|
||
STDMETHOD(SetFunctionEntry)(THIS_ BSTR DP_IN NewValue) PURE;
|
||
};
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// Consumer-supplied interface definitions.
|
||
//
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
///////////////////////////////////////
|
||
// IDTSDataPumpTransform - Required interface of the "COM Server" instantiated by ServerClsid
|
||
// passed to IDTSDataPump::AddTransform. This interface is retrieved and its methods called
|
||
// by the Pump to perform individual transforms.
|
||
//
|
||
// ServerParameters allows the DataPump Consumer to instantiate a single instance of an
|
||
// IDTSDataPumpTransform implementation and pass it to multiple IDTSDataPump::AddTransform calls.
|
||
// This is only useful for custom Transform Servers (the DTS-supplied ones ignore this), and may be
|
||
// helpful for internal summations etc. If this is done, the TransformServer should track this in its
|
||
// pvTransformServerData to optimize operations such as AddVariable, On(Row|Transform)Complete, etc.
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataPumpTransform
|
||
DECLARE_INTERFACE_(IDTSDataPumpTransform, IUnknown)
|
||
{
|
||
DTSDataPump_Unknown_Base()
|
||
|
||
// Allows the TransformServer to initialize its state for the current Transform. The output
|
||
// LPBYTE is passed to all subsequent methods, so a single TransformServer instance may be
|
||
// used to implement multiple separate transforms.
|
||
STDMETHOD(Initialize)(THIS_
|
||
DP_IN LPCOLESTR pwzName, // Transform name
|
||
DP_IN VARIANT ServerParameters, // Parameters to server for this transform
|
||
DP_OUT LPBYTE *ppvTransformServerData // Transform server state data.
|
||
) PURE;
|
||
|
||
// Validates the schema that will be transformed. Allows the TransformServer to specify
|
||
// certain modifications to the default binding modes, such as for BLOBs. The default
|
||
// p(Src|Dest)ColumnInfo->ppDTSColBinding[ii].eBindModes intialized by the DataPump are:
|
||
//
|
||
// All BLOBs must be ClientOwned by OLEDB spec, so Source and Destination BLOBs are always
|
||
// DTSBindMode_Byref_ClientOwned.
|
||
//
|
||
// Source: For efficiency, nonBLOB ((W)STR|BYTES) binding defaults to _Byref_ProviderOwned
|
||
// to avoid unnecessary copying. BSTR defaults to ProviderOwned. All other types must be
|
||
// non-Byref ClientOwned by OLEDB spec and behaviour.
|
||
//
|
||
// Destination: Because the destination data is likely to be the result of a transformation,
|
||
// destination binding always defaults to ClientOwned for all datatypes. All nonBLOB types are
|
||
// allocated Inline; this includes ((W)STR|BYTES), to minimize per-row (re)allocation overhead.
|
||
//
|
||
// A Transformation which simply passes-thru nonBLOB ((W)STR|BYTES)s or BSTRs from the Source
|
||
// IRowset to the destination (and doesn't use the TransformCopy server, which is supplied for
|
||
// this purpose) should override this to ProviderOwned to avoid unnecessary (re)allocations.
|
||
//
|
||
STDMETHOD(ValidateSchema)(THIS_
|
||
DP_IN LPBYTE pvTransformServerData, // Transform server state data.
|
||
DP_INOUT LPCDTSTransformColumnInfo pSrcColumnInfo, // Source columns and rowdata
|
||
DP_INOUT LPCDTSTransformColumnInfo pDestColumnInfo, // Dest columns and rowdata
|
||
DP_IN IDTSDataConvert *pIDTSDataConvert, // Pointer to the data conversion interface
|
||
DP_IN DTSTransformFlags eTransformFlags // Input Flags for Transformation validation and execution
|
||
) PURE;
|
||
|
||
// Adds a variable to the TransformServer's execution context. This is always called once before
|
||
// ValidateSchema, in order to add the IDTSErrorRecords object.
|
||
STDMETHOD(AddVariable)(THIS_
|
||
DP_IN LPBYTE pvTransformServerData, // Transform server state data.
|
||
DP_IN LPCOLESTR pwzName, // Variable name
|
||
DP_IN BOOL bGlobal, // For ActiveX scripts, indicates whether this variable's
|
||
// methods must be qualified by the object name.
|
||
DP_IN VARIANT Variable // Variable value; passed to and updatable by Transform
|
||
) PURE;
|
||
|
||
// Executes the transformation for a single row. This method should return a SUCCEED
|
||
// hr except in catastrophic failure; a FAILED hr here will abort the Pump. "Normal"
|
||
// errors such as data violations should be handled as a returned pTransformStatus,
|
||
// which will cause IDTSDataPumpErrorSink::OnTransformError to be called.
|
||
//
|
||
// Because some providers may have restrictions on the number of Storage Objects which
|
||
// may be open, Execute() should release any Blob Storage Objects in the source upon
|
||
// completion, rather than waiting for OnRowComplete. The DataPump handles refcounting
|
||
// for multiple transforms of its buffered Source objects. If the Blob column is
|
||
// buffered by the DataPump or the Transform has knowledge of the Source Provider, it
|
||
// can defer Release()ing the Source Storage Object until OnRowComplete. Note that
|
||
// returning DTSTransformStat_SkipFetch (and therefore not releasing the Source Storage
|
||
// Object) may require buffering of the source Blob data.
|
||
STDMETHOD(Execute)(THIS_
|
||
DP_IN LPBYTE pvTransformServerData, // Transform server state data.
|
||
DP_IN LPCDTSTransformColumnInfo pSrcColumnInfo, // Source columns and rowdata
|
||
DP_INOUT LPDTSTransformColumnInfo pDestColumnInfo, // Dest columns and rowdata
|
||
DP_IN IDTSDataConvert *pIDTSDataConvert, // Pointer to the data conversion interface
|
||
DP_OUT LPDTSTransformStatus peTransformStatus // Result of transform
|
||
) PURE;
|
||
|
||
// After a successful Fetch, the pump calls Execute and then attempts to insert the row into the
|
||
// destination IRowsetChange (if one is specified). OnRowComplete is called for every successful
|
||
// Fetch (whether the Execute() and InsertRow succeeded or failed); this allows the TransformServer
|
||
// to free per-row allocations and CLIENTOWNED data in both source and destination rows (such as
|
||
// by calling pIDTSDataConvert->ClearBindingData). A FAILED return from OnRowComplete aborts the Pump.
|
||
// hrInsert indicates whether the IRowsetChange::InsertRow() succeeded; eTransformStatus indicates
|
||
// if errors occurred such that InsertRow was not called.
|
||
//
|
||
// Note that OLEDB specifies that IRowsetChange::InsertRow() Releases any contained Storage Objects
|
||
// in the row (but not other types of "allocations"), so the Transform server must be careful not to
|
||
// call pIDTSDataConvert->ClearBindingData on an already final-released Storage Object (in the event
|
||
// that InsertRow is not called due to a Transform returning an error, the DataPump will release any
|
||
// Storage Objects in the dest row for any Transforms for which Execute was called prior to the erroring
|
||
// Transform, to present a consistent refcounting interface to TransformServers: If Execute() returned
|
||
// a non-NULL Storage Object in the row, it will be released once before OnRowComplete is called).
|
||
//
|
||
STDMETHOD(OnRowComplete)(THIS_
|
||
DP_IN LPBYTE pvTransformServerData, // Transform server state data.
|
||
DP_INOUT LPDTSTransformColumnInfo pSrcColumnInfo, // Source columns and rowdata
|
||
DP_INOUT LPDTSTransformColumnInfo pDestColumnInfo, // Dest columns and rowdata
|
||
DP_IN IDTSDataConvert *pIDTSDataConvert, // Pointer to the data conversion interface
|
||
DP_IN DTSTransformStatus eTransformStatus, // Result of Execute()
|
||
DP_IN HRESULT hrInsert // Result of IRowsetChange::InsertRow()
|
||
) PURE;
|
||
|
||
// After all rows have been transformed (or the pump has been shutdown due to errors),
|
||
// OnTransformComplete is called to give the TransformServer a chance to clean up all
|
||
// allocations made for the Transform. OnTransformComplete is called only if ValidateSchema
|
||
// returned successfully.
|
||
STDMETHOD(OnTransformComplete)(THIS_
|
||
DP_IN LPBYTE pvTransformServerData, // Transform server state data.
|
||
DP_INOUT LPDTSTransformColumnInfo pSrcColumnInfo, // Source columns and rowdata
|
||
DP_INOUT LPDTSTransformColumnInfo pDestColumnInfo, // Dest columns and rowdata
|
||
DP_IN IDTSDataConvert *pIDTSDataConvert // Pointer to the data conversion interface
|
||
) PURE;
|
||
};
|
||
|
||
|
||
///////////////////////////////////////
|
||
// IDTSDataPumpErrorSink - Specifies pump error handler sink. Only one method will
|
||
// be called for any row, and the method called indicates where the error was encountered:
|
||
// reading from source, transforming, or writing to destination.
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataPumpErrorSink
|
||
DECLARE_INTERFACE_(IDTSDataPumpErrorSink, IUnknown)
|
||
{
|
||
DTSDataPump_Unknown_Base()
|
||
|
||
// An error occurred on Binding in CreateAccessor. This is only useful for designing custom Transform
|
||
// Servers, primarily for diagnosing Blob difficulties.
|
||
STDMETHOD(OnBindingError)(THIS_
|
||
DP_IN LPBYTE pvExecUserData, // User data pointer passed to IDTSDataPump::Execute
|
||
DP_IN HRESULT hrError, // The errorcode from CreateAccessor; for Destination if pDestinationRow, else for Source.
|
||
DP_IN LPCDTSTransformColumnInfo pSourceRow, // Pointer to the source row and binding info.
|
||
DP_IN const DBBINDSTATUS *pSourceDBBindStatus, // Pointer to source binding status returns.
|
||
DP_IN LPCDTSTransformColumnInfo pDestinationRow, // Pointer to the destination row and binding info; NULL if from Source Binding error.
|
||
DP_IN const DBBINDSTATUS *pDestinationDBBindStatus // Pointer to destination binding status returns; NULL if from Source Binding error.
|
||
) PURE;
|
||
|
||
// An error occurred during GetNextRows or GetData.
|
||
STDMETHOD(OnSourceError)(THIS_
|
||
DP_IN LPBYTE pvExecUserData, // User data pointer passed to IDTSDataPump::Execute
|
||
DP_IN LPDTSTransformColumnInfo pSourceRow, // Pointer to the source row and binding info; NULL if GetNextRows or GetData failed.
|
||
DP_IN HRESULT hrError, // The errorcode from the OLEDB or system call.
|
||
DP_IN ULARGE_INTEGER uliRow, // Number of the row failing.
|
||
DP_IN ULONG cErrors, // Number of error rows encountered so far (including this one).
|
||
DP_OUT BOOL *pbAbort // Set TRUE by Sink if this error should abort IDTSDataPump::Execute.
|
||
// Otherwise, Execute() continues until MaximumErrorRowCount is exceeded.
|
||
) PURE;
|
||
|
||
// An error occurred on one or more Transforms.
|
||
STDMETHOD(OnTransformError)(THIS_
|
||
DP_IN LPBYTE pvExecUserData, // User data pointer passed to IDTSDataPump::Execute
|
||
DP_IN LPCOLESTR pwzName, // Transform name
|
||
DP_IN LPBYTE pvTransformUserData, // User data pointer passed to IDTSDataPump::AddTransform
|
||
// in LPCDTSTransformColumnsSpecification parameter.
|
||
DP_IN IDTSDataPumpTransform *pTransformServer, // The transform server raising the error; can be QI'd to custom interface for more info.
|
||
DP_IN LPDTSTransformColumnInfo pSourceRow, // Pointer to the source row and binding info.
|
||
DP_IN DTSTransformStatus TransformStatus, // Returned status code from the transformation.
|
||
DP_IN HRESULT hrTransform, // The HRESULT returned from DTSDataPumpTransform::Execute.
|
||
DP_IN ULARGE_INTEGER uliRow, // Number of the row failing.
|
||
DP_IN ULONG cErrors, // Number of error rows encountered so far (including this one).
|
||
DP_OUT BOOL *pbAbort // Set TRUE by Sink if this error should abort IDTSDataPump::Execute.
|
||
// Otherwise, Execute() continues until MaximumErrorRowCount is exceeded.
|
||
) PURE;
|
||
|
||
// An error occurred during InsertRow.
|
||
STDMETHOD(OnDestinationError)(THIS_
|
||
DP_IN LPBYTE pvExecUserData, // User data pointer passed to IDTSDataPump::Execute
|
||
DP_IN LPDTSTransformColumnInfo pSourceRow, // Pointer to the source row.
|
||
DP_IN LPDTSTransformColumnInfo pDestinationRow, // Pointer to the destination row and binding info; NULL if prior to transform execution.
|
||
DP_IN HRESULT hrError, // The errorcode from the OLEDB or system call.
|
||
DP_IN ULARGE_INTEGER uliRow, // Number of the row failing.
|
||
DP_IN ULONG cErrors, // Number of error rows encountered so far (including this one).
|
||
DP_OUT BOOL *pbAbort // Set TRUE by Sink if this error should abort IDTSDataPump::Execute.
|
||
// Otherwise, Execute() continues until MaximumErrorRowCount is exceeded.
|
||
) PURE;
|
||
};
|
||
|
||
///////////////////////////////////////
|
||
// IDTSDataDrivenQuerySink - Specifies event sink for Data Driven Queries.
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataDrivenQuerySink
|
||
DECLARE_INTERFACE_(IDTSDataDrivenQuerySink, IUnknown)
|
||
{
|
||
DTSDataPump_Unknown_Base()
|
||
|
||
STDMETHOD(OnDDQBindingError)(THIS_
|
||
DP_IN LPBYTE pvExecUserData, // User data pointer passed to IDTSDataPump::Execute
|
||
DP_IN DTSTransformStatus fQueryType, // Insert, Update, Delete, or User Query.
|
||
DP_IN HRESULT hrError, // The errorcode from CreateAccessor for Command parameters
|
||
DP_IN LPCDTSTransformColumnInfo pDestinationRow, // Pointer to the destination row and transform binding info
|
||
DP_IN ULONG cParameterColumns, // Number of parameter columns
|
||
DP_IN const DBBINDING *pParameterDBBinding, // Pointer to destination parameter bindings
|
||
DP_IN const DBBINDSTATUS *pParameterDBBindStatus // Pointer to destination parameter binding status returns
|
||
) PURE;
|
||
|
||
STDMETHOD(OnDDQCommandError)(THIS_
|
||
DP_IN LPBYTE pvExecUserData, // User data pointer passed to IDTSDataPump::Execute
|
||
DP_IN DTSTransformStatus fQueryType, // Insert, Update, Delete, or User Query.
|
||
DP_IN LPDTSTransformColumnInfo pSourceRow, // Pointer to the source row.
|
||
DP_IN LPDTSTransformColumnInfo pDestinationRow, // Pointer to the destination row and binding info.
|
||
DP_IN HRESULT hrError, // The errorcode from the OLEDB or system call.
|
||
DP_IN ULARGE_INTEGER uliRow, // Number of the row failing.
|
||
DP_IN ULONG cErrors, // Number of error rows encountered so far (including this one).
|
||
DP_OUT BOOL *pbAbort // Set TRUE by Sink if this error should abort IDTSDataPump::Execute.
|
||
// Otherwise, Execute() continues until MaximumErrorRowCount is exceeded.
|
||
) PURE;
|
||
|
||
STDMETHOD(OnDDQCommandComplete)(THIS_
|
||
DP_IN LPBYTE pvExecUserData, // User data pointer passed to IDTSDataPump::Execute
|
||
DP_IN DTSTransformStatus fQueryType, // Insert, Update, Delete, or User Query.
|
||
DP_IN LPDTSTransformColumnInfo pSourceRow, // Pointer to the source row.
|
||
DP_IN LPDTSTransformColumnInfo pDestinationRow, // Pointer to the destination row and binding info.
|
||
DP_IN LONG cDestinationRowsAffected, // Rows affected by Command; -1 if provider unable to determine.
|
||
DP_IN ULARGE_INTEGER uliRow // Number of the source row for which the Query was Execute()d.
|
||
) PURE;
|
||
};
|
||
|
||
///////////////////////////////////////
|
||
// IDTSCustomTransformUI -
|
||
// optional interface to be implemented by custom transform providers - used by DTS UI to configure the transforms
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSCustomTransformUI
|
||
DECLARE_INTERFACE_(IDTSCustomTransformUI, IUnknown)
|
||
{
|
||
DTSDataPump_Unknown_Base()
|
||
|
||
STDMETHOD(Initialize)(THIS_ DP_IN LPUNKNOWN pDTSPkgTransformObject) PURE;
|
||
STDMETHOD(New)(THIS_ DP_IN long hwndParent) PURE;
|
||
STDMETHOD(Edit)(THIS_ DP_IN long hwndParent) PURE;
|
||
STDMETHOD(Delete)(THIS_ DP_IN long hwndParent) PURE;
|
||
STDMETHOD(Help)(THIS_ DP_IN long hwndParent) PURE;
|
||
};
|
||
|
||
///////////////////////////////////////
|
||
// IDTSDataPumpProgressSink - Progress indicator event sink.
|
||
///////////////////////////////////////
|
||
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSDataPumpProgressSink
|
||
DECLARE_INTERFACE_(IDTSDataPumpProgressSink, IUnknown)
|
||
{
|
||
DTSDataPump_Unknown_Base()
|
||
|
||
STDMETHOD(OnIntervalComplete)(THIS_
|
||
DP_IN LPBYTE pvExecUserData, // User data pointer passed to IDTSDataPump::Execute
|
||
DP_IN ULARGE_INTEGER uliRowsComplete, // Total Source Rows processed at this interval (includes those skipped)
|
||
DP_OUT BOOL *pbAbort // Set TRUE by Sink to abort IDTSDataPump::Execute.
|
||
) PURE;
|
||
};
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////
|
||
// DTS Repository-support interfaces.
|
||
/////////////////////////////////////////////////////////////////////////////////
|
||
|
||
// Repository interfaces and definitions are shared between DTSDataPump and DTSPackage.
|
||
|
||
#ifdef OBJID_DtsTransformationTask
|
||
|
||
// A covering utility interface around a Repository object, provided by the DTS Package
|
||
// when requesting repository storage from a custom Task or Transformation. This interface
|
||
// is passed to IDTSRepositoryStorage methods during DTSPackage.SaveToRepository.
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSRepositoryProvider
|
||
DECLARE_INTERFACE_(INTERFACE, IUnknown)
|
||
{
|
||
DTSDataPump_Unknown_Base()
|
||
|
||
// Return a reference to the Repository object.
|
||
STDMETHOD(GetRepository)(THIS_
|
||
DP_OUT IRepository **ppIRepository // The repository object.
|
||
) PURE;
|
||
|
||
// Creates an object and sets its name.
|
||
STDMETHOD(CreateObject)(THIS_
|
||
DP_IN LPCOLESTR wzObjidClass // Repository class to create
|
||
, DP_IN LPCOLESTR wzObjidInstance // class instance (object) id, or NULL
|
||
, DP_IN LPCOLESTR wzInstanceName // class instance (object) name, or NULL
|
||
, DP_OUT IRepositoryObject **ppRepositoryObject // created object
|
||
) PURE;
|
||
|
||
// Finds an IDbmConnection object for a DTS connection in the associated DTS Package.
|
||
STDMETHOD(FindConnection)(THIS_
|
||
DP_IN LPCOLESTR wzName // DTSConnection.Name
|
||
, DP_IN long lID // DTSConnection.ID
|
||
, DP_OUT IRepositoryDispatch **ppIDbmConnection // output object
|
||
) PURE;
|
||
|
||
// When a custom Task or Transformation references a table or view, it should create a
|
||
// relationship to that table or view if the appropriate datasource and catalog's metadata
|
||
// has been scanned (by dbscanner) into the Repository. To do so, the IDTSRepositoryStorage
|
||
// implementation should call FindScannedObject, passing the name of the table or view
|
||
// to be referenced. Note that this name should be qualified as necessary to resolve
|
||
// ambiguity, if multi-part names are supported by the connection provider. This qualification
|
||
// must be done according to DBPROP_CATALOGUSAGE and DBPROP_SCHEMAUSAGE, and the following
|
||
// DBLITERALs:
|
||
// DBLITERAL_QUOTE_PREFIX
|
||
// DBLITERAL_QUOTE_SUFFIX
|
||
// DBLITERAL_CATALOG_SEPARATOR
|
||
// DBLITERAL_SCHEMA_SEPARATOR
|
||
//
|
||
// DTSPackage.SaveToRepository will search for a scanned catalog contained within any
|
||
// IDbmDataSource with IsPublic TRUE. A table or view resides in the repository as follows:
|
||
// Root(IUmlPackage).Elements
|
||
// ... possibly some intervening level of package or system...
|
||
// IDbmDataSource(IUmlPackage).Elements
|
||
// IDbmDeployedCatalog(IUmlPackage).Elements
|
||
// IDbmSchema(IUmlPackage).Elements
|
||
// IDbmDeployedTable, IDbmDeployedView
|
||
// The catalog in which wzObjectName is resolved is determined by the first name found in
|
||
// the following order:
|
||
// A catalog name parsed from wzObjectName
|
||
// DBPROP_CURRENTCATALOG after IDTSConnection.OpenConnection; this may be set by either of:
|
||
// IDTSConnection.DefaultCatalog
|
||
// IDTSConnection.ConnectionProperties(DBPROP_INIT_CATALOG)
|
||
// If DBPROP_CURRENTCATALOG is not supported, a placeholder catalog is
|
||
// created by the scanner; this catalog is used to resolve scanned object references.
|
||
//
|
||
// The schema in which wzObjectName is resolved is determined by the first name found in
|
||
// the following order:
|
||
// A schema name parsed from wzObjectName
|
||
// IDTSConnection.UserID
|
||
// IDTSConnection.ConnectionProperties(DBPROP_AUTH_USERID)
|
||
//
|
||
// Because the connection's UserID may be simply a login id and different from the actual
|
||
// object owner, wzObjectName should be qualified. Only one schema will be searched for the
|
||
// object; that schema is determined by:
|
||
// If a Schema-qualified wzObjectName is passed, that Schema is searched.
|
||
// Else if only one Schema is specified, it is searched.
|
||
// Else if a UserID is specified, it is used.
|
||
// Else EREP_OBJ_NOTFOUND.
|
||
//
|
||
// FindScannedObject returns the following, in order:
|
||
// If the call to DTSPackage.SaveToRepository specified that no scanner resolution be done,
|
||
// FindScannedObject returns NULL and S_FALSE. In this case, AddUnscannedObject should be
|
||
// called, to create an DTSPackage-level object for AddTransformationUses to relate to.
|
||
//
|
||
// If the provider does not support SchemaRowsets (necessary for scan), FindScannedObject
|
||
// returns NULL and S_FALSE.
|
||
//
|
||
// If the catalog has not been scanned, or if the call to DTSPackage.SaveToRepository
|
||
// specified to rescan, then the catalog is scanned. Any error from the dbscanner (such as
|
||
// the catalog not being found) is returned.
|
||
//
|
||
// If wzObjectName is not found, EREP_OBJ_NOTFOUND is returned.
|
||
//
|
||
// If wzObjectName is not found uniquely, such as an unqualified name appearing in more than
|
||
// one schema, EREP_OBJ_NOTFOUND is returned.
|
||
//
|
||
// If wzObjectName is found uniquely, the IDbmDeployedTable or IDbmDeployedView is placed in
|
||
// ppIScannedObject and S_OK is returned.
|
||
//
|
||
// Note that FindScannedObject should not be called for an IDbmQuery object, as these are not
|
||
// scanned into the repository as part of a Catalog; they are owned by the connection consumer.
|
||
// IDbmQuery objects should be added via AddUnscannedObject.
|
||
//
|
||
// Generally a custom Task or Transformation will do the following (with most error handling omitted
|
||
// for brevity):
|
||
// pIRepositoryProvider->CreateObject(OBJID_MyCustomTaskOrTransform
|
||
// , NULL
|
||
// , wzObjectName
|
||
// , &pICustomTaskOrTransform);
|
||
// if (referencing a table or view) {
|
||
// if FAILED(pIRepositoryProvider->FindScannedObject(<name>
|
||
// , IID_IRepositoryObject
|
||
// , pIDbmConnection
|
||
// , &pINewObject))
|
||
// return error;
|
||
// }
|
||
// if (NULL == pUnk) {
|
||
// pIRepositoryProvider->CreateObject(<parameters for the table, view, query, or other object>,
|
||
// , &pINewObject);
|
||
// pIRepositoryProvider->AddUnscannedObject(pIDbmConnection
|
||
// , pINewObject);
|
||
// }
|
||
// pIRepositoryProvider->AddTransformationUses(L"Source Table"
|
||
// , pICustomTaskOrTransform
|
||
// , pINewObject);
|
||
//
|
||
STDMETHOD(FindScannedObject)(THIS_
|
||
DP_IN LPCOLESTR wzObjectName // Name of the object (may be qualified by catalog.schema.name)
|
||
, DP_IN REFIID iidToGet // an IID the object must support; ignored if IID_NULL
|
||
, DP_IN IRepositoryDispatch *pIDbmConnection // Connection object (e.g. from FindConnection)
|
||
, DP_OUT IRepositoryObject **ppIScannedObject // returns scanned object or NULL on error.
|
||
) PURE;
|
||
|
||
// This method adds an object to the repository as a way for AddTransformationUses to form a
|
||
// relationship. This object is not visible outside the scope of the saved DTSPackage. pINewObject
|
||
// is created (e.g. by CreateObject) and may be a table or view, or query, or a specialization (derived
|
||
// class) of one, according to the following mapping:
|
||
// Object type Must support Added to
|
||
// ----------- ------------ ---------
|
||
// Query ITfmQuery ITfmTransformation(IUmlType).Members
|
||
// ITfmTransformationTask(IUmlType).Members
|
||
// Table IDbmDeployedTable Package-local DataSource/Catalog/Schema
|
||
// View IDbmDeployedView Package-local DataSource/Catalog/Schema
|
||
// other IUmlMember ITfmTransformation(IUmlType).Members
|
||
// ITfmTransformationTask(IUmlType).Members
|
||
//
|
||
STDMETHOD(AddUnscannedObject)(THIS_
|
||
DP_IN IRepositoryDispatch *pIDbmConnection // Connection object (e.g. from FindConnection)
|
||
, DP_IN IRepositoryObject *pINewObject // Task/Transform-created object.
|
||
) PURE;
|
||
|
||
// This method creates a relationship between an ITfmTransformation or ITfmTransformationTask
|
||
// and an IDbmColumnSet specialization (such as an IDbmDeployedTable, IDbmDeployedView, or ITfmQuery)
|
||
// via the ITfmTransformationUses specialization of IUmlDependency, where
|
||
// ITfmTransformationUses(IUmlDependency).SourceElement = pITaskOrTransform
|
||
// ITfmTransformationUses(IUmlDependency).TargetElement = pINewObject
|
||
//
|
||
// Any dependencies added in this manner can be retrieved during LoadFromRepository by:
|
||
// pITaskOrTransform(IID_IUmlElement).TargetDependencies
|
||
//
|
||
STDMETHOD(AddTransformationUses)(THIS_
|
||
DP_IN LPCOLESTR wzDependencyType // A string describing the dependency; e.g., L"Source Table".
|
||
, DP_IN IRepositoryObject *pITaskOrTransform // Task/Transform-created object.
|
||
, DP_IN IRepositoryObject *pINewObject // Task/Transform-created object.
|
||
) PURE;
|
||
|
||
// Creates a datatype object which maps the passed DBTYPE and other information to
|
||
// its Repository equivalent, and creates and returns a matching object.
|
||
STDMETHOD(CreateMappedDatatypeObject)(THIS_
|
||
DP_IN DBTYPE dbType // The OLEDB datatype
|
||
, DP_IN LONG lSize // Column size in characters (ignored if a fixed-length datatype)
|
||
, DP_IN LONG lPrecision // Column precision if DECIMAL or NUMERIC
|
||
, DP_IN LONG lScale // Column scale if DECIMAL or NUMERIC
|
||
, DP_OUT IRepositoryObject **ppRepositoryObject // output object
|
||
) PURE;
|
||
|
||
// Gets information from a datatype object created by CreateMappedDataTypeObject.
|
||
STDMETHOD(GetMappedDatatypeInfo)(THIS_
|
||
DP_IN IRepositoryObject *pRepositoryObject // input object
|
||
, DP_OUT DBTYPE *pdbType // The OLEDB datatype
|
||
, DP_OUT LONG *plSize // Column size in characters (ignored if a fixed-length datatype)
|
||
, DP_OUT LONG *plPrecision // Column precision if DECIMAL or NUMERIC
|
||
, DP_OUT LONG *plScale // Column scale if DECIMAL or NUMERIC
|
||
) PURE;
|
||
};
|
||
|
||
// If a custom task or custom transform server wants to manage its Repository persistence itself,
|
||
// it must implement IDTSRepositoryStorage. Otherwise, the Package will simply enumerate the
|
||
// OleAutomation properties of the custom task/transform IDispatch and store all those which
|
||
// can be Set() as (Variant)TaggedValues of an IDtsCustomTask repository object.
|
||
#undef INTERFACE
|
||
#define INTERFACE IDTSRepositoryStorage
|
||
DECLARE_INTERFACE_(INTERFACE, IUnknown)
|
||
{
|
||
DTSDataPump_Unknown_Base()
|
||
|
||
// The implementation must create its own Repository object via pIRepositoryProvider->CreateObject,
|
||
// and the returned ppIRepositoryObject must be fully populated and must support IDtsCustomTask
|
||
// (if a custom DTSPackage Task) or IDts(Blob)Transformation (if a custom DTSPump Transform server).
|
||
// After this method returns, the DTSPackage will set properties for Task Name via INamedObject::Name
|
||
// and ServerID (the ProgID or string form of CLSID by which the custom task/transformation server is
|
||
// CoCreateInstance()'d) and any other base-class values needed. Custom objects should not set tagged
|
||
// values in the base object classes, to avoid possible name conflicts.
|
||
STDMETHOD(SaveToRepository)(THIS_
|
||
DP_IN IDTSRepositoryProvider *pIRepositoryProvider
|
||
, DP_OUT IRepositoryObject **ppIRepositoryObject
|
||
) PURE;
|
||
|
||
// The implementation loads its own properties from this object. If access to the IRepository
|
||
// object is necessary, use pIRepositoryObject->get_Repository().
|
||
STDMETHOD(LoadFromRepository)(THIS_
|
||
DP_IN IDTSRepositoryProvider *pIRepositoryProvider
|
||
, DP_IN IRepositoryObject *pIRepositoryObject
|
||
) PURE;
|
||
};
|
||
|
||
#endif // def OBJID_DtsTransformationTask
|
||
|
||
#endif // ndef DTSDataPump_VersionOnly
|
||
|
||
#endif // ndef DTSDataPump_ODL_
|
||
|
||
#pragma option pop /*P_O_Pop*/
|
||
#endif // DTSDataPump_H_
|