home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / oledb / tablecopy / common.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-12  |  11.8 KB  |  440 lines

  1. //-----------------------------------------------------------------------------
  2. // Microsoft OLE DB TABLECOPY Sample
  3. // Copyright (C) 1995-1998 Microsoft Corporation
  4. //
  5. // @doc
  6. //
  7. // @module COMMON.CPP
  8. //
  9. //-----------------------------------------------------------------------------
  10.  
  11. /////////////////////////////////////////////////////////////////////////////
  12. // Include
  13. //
  14. /////////////////////////////////////////////////////////////////////////////
  15. #include "winmain.h"
  16. #include "common.h"
  17. #include "tablecopy.h"
  18. #include "table.h"
  19.  
  20.  
  21. /////////////////////////////////////////////////////////////////////////////
  22. //     Defines
  23. //
  24. /////////////////////////////////////////////////////////////////////////////
  25.  
  26. //Displays values like VALUE as   VALUE , L"VALUE"
  27. #define VALUE_WCHAR(value) value, L#value
  28.  
  29. typedef struct _TYPEMAP
  30. {
  31.     DBTYPE        wType;                // The sql type value
  32.     WCHAR*        pwszTypeName;        // Name for display
  33. } TYPEMAP;
  34.  
  35. TYPEMAP rgDBTypes[] = 
  36. {
  37.     VALUE_WCHAR(NULL),
  38.     VALUE_WCHAR(DBTYPE_I1),
  39.     VALUE_WCHAR(DBTYPE_I2),
  40.     VALUE_WCHAR(DBTYPE_I4),
  41.     VALUE_WCHAR(DBTYPE_I8),
  42.     VALUE_WCHAR(DBTYPE_UI1),
  43.     VALUE_WCHAR(DBTYPE_UI2),
  44.     VALUE_WCHAR(DBTYPE_UI4),
  45.     VALUE_WCHAR(DBTYPE_UI8),
  46.     VALUE_WCHAR(DBTYPE_R4),
  47.     VALUE_WCHAR(DBTYPE_R8),
  48.     VALUE_WCHAR(DBTYPE_CY),
  49.     VALUE_WCHAR(DBTYPE_DECIMAL),
  50.     VALUE_WCHAR(DBTYPE_NUMERIC),
  51.     VALUE_WCHAR(DBTYPE_BOOL),
  52.     VALUE_WCHAR(DBTYPE_ERROR),
  53.     VALUE_WCHAR(DBTYPE_UDT),
  54.     VALUE_WCHAR(DBTYPE_VARIANT),
  55.     VALUE_WCHAR(DBTYPE_IDISPATCH),
  56.     VALUE_WCHAR(DBTYPE_IUNKNOWN),
  57.     VALUE_WCHAR(DBTYPE_GUID),
  58.     VALUE_WCHAR(DBTYPE_DATE),
  59.     VALUE_WCHAR(DBTYPE_DBDATE),
  60.     VALUE_WCHAR(DBTYPE_DBTIME),
  61.     VALUE_WCHAR(DBTYPE_DBTIMESTAMP),
  62.     VALUE_WCHAR(DBTYPE_BSTR),
  63.     VALUE_WCHAR(DBTYPE_STR),
  64.     VALUE_WCHAR(DBTYPE_WSTR),
  65.     VALUE_WCHAR(DBTYPE_BYTES),
  66. };
  67.  
  68.  
  69.  
  70. /////////////////////////////////////////////////////////////////////////////
  71. // HRESULT ConvertToMBCS
  72. //
  73. /////////////////////////////////////////////////////////////////////////////
  74. HRESULT ConvertToMBCS(WCHAR* pwsz, CHAR* psz, ULONG cStrLen)
  75. {
  76.     ASSERT(pwsz && psz);
  77.  
  78.     //Convert the string to MBCS
  79.     INT iResult = WideCharToMultiByte(CP_ACP, 0, pwsz, -1, psz, cStrLen, NULL, NULL);
  80.     return iResult ? S_OK : E_FAIL;
  81. }
  82.  
  83. /////////////////////////////////////////////////////////////////////////////
  84. // HRESULT ConvertToWCHAR
  85. //
  86. /////////////////////////////////////////////////////////////////////////////
  87. HRESULT ConvertToWCHAR(CHAR* psz, WCHAR* pwsz, ULONG cStrLen)
  88. {
  89.     ASSERT(psz && pwsz);
  90.  
  91.     //Convert the string to MBCS
  92.     INT iResult = MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, cStrLen);
  93.     return iResult ? S_OK : E_FAIL;
  94. }
  95.  
  96.  
  97. /////////////////////////////////////////////////////////////////////////////
  98. // WCHAR* wcsDuplicate
  99. //
  100. /////////////////////////////////////////////////////////////////////////////
  101. WCHAR* wcsDuplicate(WCHAR* pwsz)
  102. {
  103.     ASSERT(pwsz);
  104.     
  105.     //no-op case
  106.     if(!pwsz)
  107.         return NULL;
  108.     
  109.     ULONG cLen    = wcslen(pwsz);
  110.  
  111.     //Allocate space for the string
  112.     WCHAR* pwszBuffer = NULL;
  113.     SAFE_ALLOC(pwszBuffer, WCHAR, cLen+1);
  114.  
  115.     //Now copy the string
  116.     wcscpy(pwszBuffer, pwsz);
  117.  
  118. CLEANUP:
  119.     return pwszBuffer;
  120. }
  121.  
  122.  
  123. /////////////////////////////////////////////////////////////////////////////
  124. // ULONG GetCreateParams
  125. //
  126. /////////////////////////////////////////////////////////////////////////////
  127. ULONG GetCreateParams(WCHAR* pwszCreateParam)
  128. {
  129.     ASSERT(pwszCreateParam);
  130.     
  131.     ULONG    ulType = 0;                                  
  132.     
  133.     if(wcsstr(pwszCreateParam, L"precision") || wcsstr(pwszCreateParam, L"PRECISION"))
  134.         ulType |= CP_PRECISION;
  135.     if(wcsstr(pwszCreateParam, L"scale") || wcsstr(pwszCreateParam, L"SCALE"))
  136.         ulType |= CP_SCALE;
  137.     if(wcsstr(pwszCreateParam, L"length") || wcsstr(pwszCreateParam, L"LENGTH"))
  138.         ulType |= CP_LENGTH;
  139.     if(wcsstr(pwszCreateParam, L"max length") || wcsstr(pwszCreateParam, L"MAX LENGTH"))
  140.         ulType |= CP_MAXLENGTH;
  141.  
  142.     return ulType;
  143. }
  144.  
  145.  
  146. /////////////////////////////////////////////////////////////////////////////
  147. // BOOL IsVariableType
  148. //
  149. /////////////////////////////////////////////////////////////////////////////
  150. BOOL IsVariableType(DBTYPE wType)
  151. {
  152.     //According to OLEDB Spec Appendix A (Variable-Length Data Types)
  153.     switch(wType) 
  154.     {
  155.         case DBTYPE_STR:
  156.         case DBTYPE_WSTR:
  157.         case DBTYPE_BYTES:
  158.             return TRUE;
  159.     }
  160.     return FALSE;
  161. }
  162.  
  163.  
  164. /////////////////////////////////////////////////////////////////////////////
  165. // BOOL IsFixedType
  166. //
  167. /////////////////////////////////////////////////////////////////////////////
  168. BOOL IsFixedType(DBTYPE wType)
  169. {
  170.     return !IsVariableType(wType);
  171. }
  172.  
  173. /////////////////////////////////////////////////////////////////////////////
  174. // BOOL IsNumericType
  175. //
  176. /////////////////////////////////////////////////////////////////////////////
  177. BOOL IsNumericType(DBTYPE wType)
  178. {
  179.     //According to OLEDB Spec Appendix A (Numeric Data Types)
  180.     switch(wType) 
  181.     {
  182.         case DBTYPE_I1:
  183.         case DBTYPE_I2:
  184.         case DBTYPE_I4:
  185.         case DBTYPE_I8:
  186.         case DBTYPE_UI1:
  187.         case DBTYPE_UI2:
  188.         case DBTYPE_UI4:
  189.         case DBTYPE_UI8:
  190.         case DBTYPE_R4:
  191.         case DBTYPE_R8:
  192.         case DBTYPE_CY:
  193.         case DBTYPE_DECIMAL:
  194.         case DBTYPE_NUMERIC:
  195.             return TRUE;
  196.     }
  197.     return FALSE;
  198. }
  199.  
  200. /////////////////////////////////////////////////////////////////////////////
  201. // WCHAR* GetDBTypeName
  202. //
  203. /////////////////////////////////////////////////////////////////////////////
  204. WCHAR* GetDBTypeName(DBTYPE wType)
  205. {
  206.     // Do a table look-up on the type
  207.     for(ULONG i=0; i<NUMELE(rgDBTypes); i++)
  208.     {
  209.         if(wType == rgDBTypes[i].wType) 
  210.             return rgDBTypes[i].pwszTypeName;
  211.     }
  212.  
  213.     return rgDBTypes[0].pwszTypeName;
  214. }
  215.  
  216.  
  217. /////////////////////////////////////////////////////////////////////////////
  218. // BOOL GetPromotedType
  219. //
  220. /////////////////////////////////////////////////////////////////////////////
  221. BOOL GetPromotedType(DBTYPE* pwType)
  222. {
  223.     ASSERT(pwType);
  224.  
  225.     //For fixed types we first consider promoting signed types
  226.     //to unsigned types first, before promoting up to the 
  227.     //next actual type.  Like DBTYPE_I1 -> DBTYPE_UI1,
  228.     //instead of going directly to DBTYPE_I2.
  229.  
  230.     switch(*pwType) 
  231.     {
  232.  
  233.         // Integer family
  234.         case DBTYPE_BOOL:
  235.             *pwType = DBTYPE_I1;
  236.             break;
  237.  
  238.         case DBTYPE_I1:
  239.             *pwType = DBTYPE_UI1;
  240.             break;
  241.  
  242.         case DBTYPE_UI1:
  243.             *pwType = DBTYPE_I2;
  244.             break;
  245.             
  246.         case DBTYPE_I2:
  247.             *pwType = DBTYPE_UI2;
  248.             break;
  249.                 
  250.         case DBTYPE_UI2:
  251.             *pwType = DBTYPE_I4;
  252.             break;
  253.             
  254.         case DBTYPE_I4:
  255.             *pwType = DBTYPE_UI4;
  256.             break;
  257.  
  258.         case DBTYPE_UI4:
  259.         case DBTYPE_CY:
  260.             *pwType = DBTYPE_I8;
  261.             break;
  262.         
  263.         case DBTYPE_I8:
  264.             *pwType = DBTYPE_UI8;
  265.             break;
  266.  
  267.         case DBTYPE_UI8:
  268.             *pwType = DBTYPE_NUMERIC;
  269.             break;
  270.  
  271.  
  272.         // Floating-point type family.  FLOAT and DOUBLE actually
  273.         // have the same precision, so do a mutual promotion (that
  274.         // is, allow FLOAT to become DOUBLE and DOUBLE to become
  275.         // FLOAT) before going to CHAR.
  276.         //
  277.         case DBTYPE_R4:
  278.             *pwType = DBTYPE_R8;
  279.             break;
  280.             
  281.         // Fixed-point exact numerics. Ordering of the two types
  282.         // is unimportant--for our purposes they have exactly the
  283.         // same semantics.  
  284.         //
  285.         case DBTYPE_NUMERIC:
  286.             *pwType = DBTYPE_DECIMAL;
  287.             break;
  288.             
  289.         case DBTYPE_DECIMAL:
  290.             *pwType = DBTYPE_R8;
  291.             break;
  292.                         
  293.         // Binary types
  294.         case DBTYPE_BYTES:
  295.             *pwType = DBTYPE_STR;
  296.             break;
  297.  
  298.         // Date/Time family
  299.         case DBTYPE_DATE:
  300.         case DBTYPE_DBTIME:
  301.         case DBTYPE_DBDATE:
  302.             *pwType = DBTYPE_DBTIMESTAMP;
  303.             break;
  304.             
  305.         case DBTYPE_R8:
  306.         case DBTYPE_DBTIMESTAMP:
  307.             *pwType = DBTYPE_BYTES;
  308.             break;
  309.  
  310.         // Allow WSTR to STR.
  311.         case DBTYPE_WSTR:
  312.             *pwType = DBTYPE_STR;
  313.             break;
  314.  
  315.         case DBTYPE_VARIANT:
  316.             *pwType = DBTYPE_STR;
  317.             break;
  318.  
  319.         default:
  320.             return FALSE;
  321.     }
  322.  
  323.     return TRUE;
  324. }
  325.  
  326.     
  327.  
  328. ///////////////////////////////////////////////////////////////
  329. // BOOL FreeBindingData
  330. //
  331. ///////////////////////////////////////////////////////////////
  332. BOOL FreeBindingData(ULONG cBindings, DBBINDING* rgBindings, void* pData)
  333. {
  334.     ASSERT(pData);
  335.     
  336.     //Need to walk the array and free any other alloc memory
  337.     for(ULONG i=0; i<cBindings; i++)
  338.     {
  339.         //Free any "out-of-line" memory
  340.         //VARIANT
  341.         if(rgBindings[i].wType == DBTYPE_VARIANT)
  342.         {
  343.             VARIANT* pVariant = (VARIANT*)&BINDING_VALUE(rgBindings[i], pData);
  344.             FreeVariants(1, pVariant);
  345.         }
  346.  
  347.         //Free any pObjects
  348.         SAFE_FREE(rgBindings[i].pObject);
  349.     }
  350.  
  351.     return TRUE;
  352. }
  353.  
  354.  
  355. ///////////////////////////////////////////////////////////////
  356. // BOOL FreeBindings
  357. //
  358. ///////////////////////////////////////////////////////////////
  359. BOOL FreeBindings(ULONG cBindings, DBBINDING* rgBindings)
  360. {
  361.     //Need to walk the array and free any other alloc memory
  362.     for(ULONG i=0; i<cBindings; i++)
  363.     {
  364.         //Free any pObjects
  365.         SAFE_FREE(rgBindings[i].pObject);
  366.     }
  367.  
  368.     //Now we can free the outer struct
  369.     SAFE_FREE(rgBindings);
  370.     return TRUE;
  371. }
  372.  
  373.  
  374.  
  375. ///////////////////////////////////////////////////////////////
  376. // Static Strings Messages
  377. //
  378. ///////////////////////////////////////////////////////////////
  379.  
  380. extern WCHAR wsz_OLEDB[]                = L"Microsoft OLE DB TableCopy";
  381. extern WCHAR wsz_SUCCESS[]                = L"Microsoft OLE DB TableCopy - Success";
  382. extern WCHAR wsz_WARNING[]                = L"Microsoft OLE DB TableCopy - Warning";
  383. extern WCHAR wsz_INFO[]                    = L"Microsoft OLE DB TableCopy - Info";
  384. extern WCHAR wsz_ERROR[]                = L"Microsoft OLE DB TableCopy - Error";
  385. extern WCHAR wsz_CANCEL[]                = L"Microsoft OLE DB TableCopy - Cancel";
  386. extern WCHAR wsz_ERRORINFO[]            = L"Microsoft OLE DB TableCopy - IErrorInfo";
  387.                                  
  388. //Copying Status
  389. extern WCHAR wsz_COPYING[]                 = L"Copying records";
  390. extern WCHAR wsz_COPIED_RECORDS[]        = L"%lu records copied";
  391. extern WCHAR wsz_COPY_SUCCESS[]            = L"Copy succeeded, %lu records copied!";
  392. extern WCHAR wsz_COPY_FAILURE[]            = L"Copy failed!";
  393. extern WCHAR wsz_CANCEL_OP[]            = L"Do you want to cancel?";
  394. extern WCHAR wsz_TYPEMAPPING_FAILURE[]    = L"Mapping of Data Types Failed!";
  395.  
  396. //Tables
  397. extern WCHAR wsz_CREATE_TABLE[]            = L"CREATE TABLE ";
  398. extern WCHAR wsz_DROP_TABLE_[]            = L"DROP TABLE %s ";
  399. extern WCHAR wsz_ASK_DROP_TABLE_[]         = L"%s %s already exists.  Would you like to drop it?";
  400. extern WCHAR wsz_SAME_TABLE_NAME[]         = L"Target %s name must be different on the same DataSource";
  401. extern WCHAR wsz_FROMTABLEHELP_[]        = L"Select Desired %s and Columns to Copy";
  402. extern WCHAR wsz_FROMQUALTABLE_[]        = L"%s, %d Column(s)";
  403. extern WCHAR wsz_TOTABLEHELP_[]            = L"Select Target %s Name";
  404.  
  405. //Indexes
  406. extern WCHAR wsz_CREATE_INDEX_[]        = L"CREATE%sINDEX ";
  407. extern WCHAR wsz_UNIQUE_INDEX[]            = L" UNIQUE ";
  408. extern WCHAR wsz_INDEX_DESC[]             = L" DESC ";
  409. extern WCHAR wsz_INDEX_FAILED_[]        = L"INDEX %s failed to be created.  Would you like to Continue?";
  410.  
  411. //Columns
  412. extern WCHAR wsz_NO_TYPE_MATCH_[]        = L"Target Data type not found for %s type";
  413. extern WCHAR wsz_NO_TYPE_FOUND_[]        = L"Source Data type not found for %s type";
  414.  
  415. extern WCHAR wsz_CONNECT_STRING_[]        = L"%s    %s    %s %s    %s %s";
  416. extern WCHAR wsz_TYPES_STRING_[]        = L"%s    %s    %s=%s";
  417. extern WCHAR wsz_NOT_CONNECTED[]        = L"Not Connected: Press Connect to establish a connection";
  418.  
  419. extern WCHAR wsz_PROVIDER_INFO_[]        = L"%-20s     %s";
  420.  
  421. extern WCHAR wsz_INVALID_VALUE_[]        = L"Invalid Value '%s' specified.  Please specify a value >= %lu and <= %lu.";
  422. extern WCHAR wsz_READONLY_DATASOURCE_[]    = L"Datasource %s is marked as read only, it may not be updateable.";
  423.  
  424. //Query
  425. extern WCHAR wsz_SHOW_SQL_[]            = L"DSN = %s\n\nSQL = %s";
  426. extern WCHAR wsz_SELECT[]                = L" SELECT ";
  427. extern WCHAR wsz_FROM[]                    = L" FROM ";
  428. extern WCHAR wsz_BOGUS_WHERE[]            = L" WHERE 0 = 1";
  429. extern WCHAR wsz_INSERT_INTO[]            = L"INSERT INTO ";
  430. extern WCHAR wsz_VALUES_CLAUSE[]        = L" ) VALUES ( ";
  431. extern WCHAR wsz_PARAM[]                = L"?";
  432. extern WCHAR wsz_PRIMARY_KEY[]            = L" PRIMARY KEY";
  433.  
  434. //General String Values
  435. extern WCHAR wsz_COMMA[]                = L", ";
  436. extern WCHAR wsz_LPAREN[]                = L" ( ";
  437. extern WCHAR wsz_RPAREN[]                = L" ) ";
  438. extern WCHAR wsz_SPACE[]                = L" ";
  439. extern WCHAR wsz_PERIOD[]                = L".";
  440.