2025-11-28 00:35:46 +09:00

440 lines
11 KiB
C++

//-----------------------------------------------------------------------------
// Microsoft OLE DB TABLECOPY Sample
// Copyright (C) 1995-2000 Microsoft Corporation
//
// @doc
//
// @module COMMON.CPP
//
//-----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
// Include
//
/////////////////////////////////////////////////////////////////////////////
#include "winmain.h"
#include "common.h"
#include "tablecopy.h"
#include "table.h"
/////////////////////////////////////////////////////////////////////////////
// Defines
//
/////////////////////////////////////////////////////////////////////////////
//Displays values like VALUE as VALUE , L"VALUE"
#define VALUE_WCHAR(value) value, L#value
typedef struct _TYPEMAP
{
DBTYPE wType; // The sql type value
WCHAR* pwszTypeName; // Name for display
} TYPEMAP;
TYPEMAP rgDBTypes[] =
{
VALUE_WCHAR(NULL),
VALUE_WCHAR(DBTYPE_I1),
VALUE_WCHAR(DBTYPE_I2),
VALUE_WCHAR(DBTYPE_I4),
VALUE_WCHAR(DBTYPE_I8),
VALUE_WCHAR(DBTYPE_UI1),
VALUE_WCHAR(DBTYPE_UI2),
VALUE_WCHAR(DBTYPE_UI4),
VALUE_WCHAR(DBTYPE_UI8),
VALUE_WCHAR(DBTYPE_R4),
VALUE_WCHAR(DBTYPE_R8),
VALUE_WCHAR(DBTYPE_CY),
VALUE_WCHAR(DBTYPE_DECIMAL),
VALUE_WCHAR(DBTYPE_NUMERIC),
VALUE_WCHAR(DBTYPE_BOOL),
VALUE_WCHAR(DBTYPE_ERROR),
VALUE_WCHAR(DBTYPE_UDT),
VALUE_WCHAR(DBTYPE_VARIANT),
VALUE_WCHAR(DBTYPE_IDISPATCH),
VALUE_WCHAR(DBTYPE_IUNKNOWN),
VALUE_WCHAR(DBTYPE_GUID),
VALUE_WCHAR(DBTYPE_DATE),
VALUE_WCHAR(DBTYPE_DBDATE),
VALUE_WCHAR(DBTYPE_DBTIME),
VALUE_WCHAR(DBTYPE_DBTIMESTAMP),
VALUE_WCHAR(DBTYPE_BSTR),
VALUE_WCHAR(DBTYPE_STR),
VALUE_WCHAR(DBTYPE_WSTR),
VALUE_WCHAR(DBTYPE_BYTES),
};
/////////////////////////////////////////////////////////////////////////////
// HRESULT ConvertToMBCS
//
/////////////////////////////////////////////////////////////////////////////
HRESULT ConvertToMBCS(WCHAR* pwsz, CHAR* psz, ULONG cStrLen)
{
ASSERT(pwsz && psz);
//Convert the string to MBCS
INT iResult = WideCharToMultiByte(CP_ACP, 0, pwsz, -1, psz, cStrLen, NULL, NULL);
return iResult ? S_OK : E_FAIL;
}
/////////////////////////////////////////////////////////////////////////////
// HRESULT ConvertToWCHAR
//
/////////////////////////////////////////////////////////////////////////////
HRESULT ConvertToWCHAR(CHAR* psz, WCHAR* pwsz, ULONG cStrLen)
{
ASSERT(psz && pwsz);
//Convert the string to MBCS
INT iResult = MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, cStrLen);
return iResult ? S_OK : E_FAIL;
}
/////////////////////////////////////////////////////////////////////////////
// WCHAR* wcsDuplicate
//
/////////////////////////////////////////////////////////////////////////////
WCHAR* wcsDuplicate(WCHAR* pwsz)
{
ASSERT(pwsz);
//no-op case
if(!pwsz)
return NULL;
size_t cLen = wcslen(pwsz);
//Allocate space for the string
WCHAR* pwszBuffer = NULL;
SAFE_ALLOC(pwszBuffer, WCHAR, cLen+1);
//Now copy the string
StringCchCopyW(pwszBuffer, cLen+1, pwsz);
CLEANUP:
return pwszBuffer;
}
/////////////////////////////////////////////////////////////////////////////
// ULONG GetCreateParams
//
/////////////////////////////////////////////////////////////////////////////
ULONG GetCreateParams(WCHAR* pwszCreateParam)
{
ASSERT(pwszCreateParam);
ULONG ulType = 0;
if(wcsstr(pwszCreateParam, L"precision") || wcsstr(pwszCreateParam, L"PRECISION"))
ulType |= CP_PRECISION;
if(wcsstr(pwszCreateParam, L"scale") || wcsstr(pwszCreateParam, L"SCALE"))
ulType |= CP_SCALE;
if(wcsstr(pwszCreateParam, L"length") || wcsstr(pwszCreateParam, L"LENGTH"))
ulType |= CP_LENGTH;
if(wcsstr(pwszCreateParam, L"max length") || wcsstr(pwszCreateParam, L"MAX LENGTH"))
ulType |= CP_MAXLENGTH;
return ulType;
}
/////////////////////////////////////////////////////////////////////////////
// BOOL IsVariableType
//
/////////////////////////////////////////////////////////////////////////////
BOOL IsVariableType(DBTYPE wType)
{
//According to OLEDB Spec Appendix A (Variable-Length Data Types)
switch(wType)
{
case DBTYPE_STR:
case DBTYPE_WSTR:
case DBTYPE_BYTES:
return TRUE;
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// BOOL IsFixedType
//
/////////////////////////////////////////////////////////////////////////////
BOOL IsFixedType(DBTYPE wType)
{
return !IsVariableType(wType);
}
/////////////////////////////////////////////////////////////////////////////
// BOOL IsNumericType
//
/////////////////////////////////////////////////////////////////////////////
BOOL IsNumericType(DBTYPE wType)
{
//According to OLEDB Spec Appendix A (Numeric Data Types)
switch(wType)
{
case DBTYPE_I1:
case DBTYPE_I2:
case DBTYPE_I4:
case DBTYPE_I8:
case DBTYPE_UI1:
case DBTYPE_UI2:
case DBTYPE_UI4:
case DBTYPE_UI8:
case DBTYPE_R4:
case DBTYPE_R8:
case DBTYPE_CY:
case DBTYPE_DECIMAL:
case DBTYPE_NUMERIC:
return TRUE;
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// WCHAR* GetDBTypeName
//
/////////////////////////////////////////////////////////////////////////////
WCHAR* GetDBTypeName(DBTYPE wType)
{
// Do a table look-up on the type
for(ULONG i=0; i<NUMELE(rgDBTypes); i++)
{
if(wType == rgDBTypes[i].wType)
return rgDBTypes[i].pwszTypeName;
}
return rgDBTypes[0].pwszTypeName;
}
/////////////////////////////////////////////////////////////////////////////
// BOOL GetPromotedType
//
/////////////////////////////////////////////////////////////////////////////
BOOL GetPromotedType(DBTYPE* pwType)
{
ASSERT(pwType);
//For fixed types we first consider promoting signed types
//to unsigned types first, before promoting up to the
//next actual type. Like DBTYPE_I1 -> DBTYPE_UI1,
//instead of going directly to DBTYPE_I2.
switch(*pwType)
{
// Integer family
case DBTYPE_BOOL:
*pwType = DBTYPE_I1;
break;
case DBTYPE_I1:
*pwType = DBTYPE_UI1;
break;
case DBTYPE_UI1:
*pwType = DBTYPE_I2;
break;
case DBTYPE_I2:
*pwType = DBTYPE_UI2;
break;
case DBTYPE_UI2:
*pwType = DBTYPE_I4;
break;
case DBTYPE_I4:
*pwType = DBTYPE_UI4;
break;
case DBTYPE_UI4:
case DBTYPE_CY:
*pwType = DBTYPE_I8;
break;
case DBTYPE_I8:
*pwType = DBTYPE_UI8;
break;
case DBTYPE_UI8:
*pwType = DBTYPE_NUMERIC;
break;
// Floating-point type family. FLOAT and DOUBLE actually
// have the same precision, so do a mutual promotion (that
// is, allow FLOAT to become DOUBLE and DOUBLE to become
// FLOAT) before going to CHAR.
//
case DBTYPE_R4:
*pwType = DBTYPE_R8;
break;
// Fixed-point exact numerics. Ordering of the two types
// is unimportant--for our purposes they have exactly the
// same semantics.
//
case DBTYPE_NUMERIC:
*pwType = DBTYPE_DECIMAL;
break;
case DBTYPE_DECIMAL:
*pwType = DBTYPE_R8;
break;
// Binary types
case DBTYPE_BYTES:
*pwType = DBTYPE_STR;
break;
// Date/Time family
case DBTYPE_DATE:
case DBTYPE_DBTIME:
case DBTYPE_DBDATE:
*pwType = DBTYPE_DBTIMESTAMP;
break;
case DBTYPE_R8:
case DBTYPE_DBTIMESTAMP:
*pwType = DBTYPE_BYTES;
break;
// Allow WSTR to STR.
case DBTYPE_WSTR:
*pwType = DBTYPE_STR;
break;
case DBTYPE_VARIANT:
*pwType = DBTYPE_STR;
break;
default:
return FALSE;
}
return TRUE;
}
///////////////////////////////////////////////////////////////
// BOOL FreeBindingData
//
///////////////////////////////////////////////////////////////
BOOL FreeBindingData(ULONG cBindings, DBBINDING* rgBindings, void* pData)
{
ASSERT(pData);
//Need to walk the array and free any other alloc memory
for(ULONG i=0; i<cBindings; i++)
{
//Free any "out-of-line" memory
//VARIANT
if(rgBindings[i].wType == DBTYPE_VARIANT)
{
VARIANT* pVariant = (VARIANT*)&BINDING_VALUE(rgBindings[i], pData);
FreeVariants(1, pVariant);
}
//Free any pObjects
SAFE_FREE(rgBindings[i].pObject);
}
return TRUE;
}
///////////////////////////////////////////////////////////////
// BOOL FreeBindings
//
///////////////////////////////////////////////////////////////
BOOL FreeBindings(ULONG cBindings, DBBINDING* rgBindings)
{
//Need to walk the array and free any other alloc memory
for(ULONG i=0; i<cBindings; i++)
{
//Free any pObjects
SAFE_FREE(rgBindings[i].pObject);
}
//Now we can free the outer struct
SAFE_FREE(rgBindings);
return TRUE;
}
///////////////////////////////////////////////////////////////
// Static Strings Messages
//
///////////////////////////////////////////////////////////////
extern WCHAR wsz_OLEDB[] = L"Microsoft OLE DB TableCopy";
extern WCHAR wsz_SUCCESS[] = L"Microsoft OLE DB TableCopy - Success";
extern WCHAR wsz_WARNING[] = L"Microsoft OLE DB TableCopy - Warning";
extern WCHAR wsz_INFO[] = L"Microsoft OLE DB TableCopy - Info";
extern WCHAR wsz_ERROR[] = L"Microsoft OLE DB TableCopy - Error";
extern WCHAR wsz_CANCEL[] = L"Microsoft OLE DB TableCopy - Cancel";
extern WCHAR wsz_ERRORINFO[] = L"Microsoft OLE DB TableCopy - IErrorInfo";
//Copying Status
extern WCHAR wsz_COPYING[] = L"Copying records";
extern WCHAR wsz_COPIED_RECORDS[] = L"%Id records copied";
extern WCHAR wsz_COPY_SUCCESS[] = L"Copy succeeded, %Id records copied!";
extern WCHAR wsz_COPY_FAILURE[] = L"Copy failed!";
extern WCHAR wsz_CANCEL_OP[] = L"Do you want to cancel?";
extern WCHAR wsz_TYPEMAPPING_FAILURE[] = L"Mapping of Data Types Failed!";
//Tables
extern WCHAR wsz_CREATE_TABLE[] = L"CREATE TABLE ";
extern WCHAR wsz_DROP_TABLE_[] = L"DROP TABLE %s ";
extern WCHAR wsz_ASK_DROP_TABLE_[] = L"%s %s already exists. Would you like to drop it?";
extern WCHAR wsz_SAME_TABLE_NAME[] = L"Target %s name must be different on the same DataSource";
extern WCHAR wsz_FROMTABLEHELP_[] = L"Select Desired %s and Columns to Copy";
extern WCHAR wsz_FROMQUALTABLE_[] = L"%s, %Id Column(s)";
extern WCHAR wsz_TOTABLEHELP_[] = L"Select Target %s Name";
//Indexes
extern WCHAR wsz_CREATE_INDEX_[] = L"CREATE%sINDEX ";
extern WCHAR wsz_UNIQUE_INDEX[] = L" UNIQUE ";
extern WCHAR wsz_INDEX_DESC[] = L" DESC ";
extern WCHAR wsz_INDEX_FAILED_[] = L"INDEX %s failed to be created. Would you like to Continue?";
//Columns
extern WCHAR wsz_NO_TYPE_MATCH_[] = L"Target Data type not found for %s type";
extern WCHAR wsz_NO_TYPE_FOUND_[] = L"Source Data type not found for %s type";
extern WCHAR wsz_CONNECT_STRING_[] = L"%s %s %s %s %s %s";
extern WCHAR wsz_TYPES_STRING_[] = L"%s %s %s=%s";
extern WCHAR wsz_NOT_CONNECTED[] = L"Not Connected: Press Connect to establish a connection";
extern WCHAR wsz_PROVIDER_INFO_[] = L"%s";
extern WCHAR wsz_INVALID_VALUE_[] = L"Invalid Value '%s' specified. Please specify a value >= %lu and <= %lu.";
extern WCHAR wsz_READONLY_DATASOURCE_[] = L"Datasource %s is marked as read only, it may not be updateable.";
//Query
extern WCHAR wsz_SHOW_SQL_[] = L"DSN = %s\n\nSQL = %s";
extern WCHAR wsz_SELECT[] = L" SELECT ";
extern WCHAR wsz_FROM[] = L" FROM ";
extern WCHAR wsz_BOGUS_WHERE[] = L" WHERE 0 = 1";
extern WCHAR wsz_INSERT_INTO[] = L"INSERT INTO ";
extern WCHAR wsz_VALUES_CLAUSE[] = L" ) VALUES ( ";
extern WCHAR wsz_PARAM[] = L"?";
extern WCHAR wsz_PRIMARY_KEY[] = L" PRIMARY KEY";
//General String Values
extern WCHAR wsz_COMMA[] = L", ";
extern WCHAR wsz_LPAREN[] = L" ( ";
extern WCHAR wsz_RPAREN[] = L" ) ";
extern WCHAR wsz_SPACE[] = L" ";
extern WCHAR wsz_PERIOD[] = L".";