List:Commits« Previous MessageNext Message »
From:pharvey Date:July 22 2006 6:26pm
Subject:Connector/ODBC 5 commit: r457 - trunk/examples/CPP/7/ADO
View as plain text  
Added:
   trunk/examples/CPP/7/ADO/5.gif
Modified:
   trunk/examples/CPP/7/ADO/main.cpp
Log:
work to make ADO example more relevant (to at least one customer anyway)

Added: trunk/examples/CPP/7/ADO/5.gif
===================================================================
(Binary files differ)


Property changes on: trunk/examples/CPP/7/ADO/5.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: trunk/examples/CPP/7/ADO/main.cpp
===================================================================
--- trunk/examples/CPP/7/ADO/main.cpp	2006-07-21 00:22:58 UTC (rev 456)
+++ trunk/examples/CPP/7/ADO/main.cpp	2006-07-22 18:26:17 UTC (rev 457)
@@ -21,6 +21,7 @@
                         - allow big results
                         - use compressed protocol
                 - alter the connection information in the code below
+                - BINARY_FILENAME must exist in current dir when prg exec
 
     \warning    Do not use this in a production environment or in any environment where
you may suffer
                 grief if things go horribly wrong. Use at your own risk.
@@ -31,7 +32,9 @@
 
 #include <ole2.h>
 #include <stdio.h>
-#include <conio.h>
+#include <io.h>
+#include <fcntl.h>
+#include <sys\stat.h>
 
 /*!
     \note
@@ -59,15 +62,19 @@
 char *pszPassword           = "pharvey";
 
 // sample data
-UCHAR   pData[]   = "12345678901234567890123456789012345678901234567890";  
-int     nDataLen  = 10; // data truncation errors if this is larger than strlen pData or
size of column
+UCHAR   pDataText[]     = "12345678901234567890123456789012345678901234567890";  
+int     nDataLengthText = 10; // data truncation errors if this is larger than strlen
pDataText or size of column
 
+#define BINARY_FILENAME "5.gif"
+UCHAR * pDataBinary         = NULL;
+long    nDataLengthBinary   = 0;
+
 /*!
     \brief  Print the providers errors.
 */
-void doPrintProviderError( _ConnectionPtr pConnection )
+void doPrintProviderError( const char *pszFileName, int nLine, const char *pszFunction,
_ConnectionPtr pConnection )
 {
-    ErrorPtr  pErr = NULL;
+    ErrorPtr pErr = NULL;
 
     // do we have errors?
     if ( pConnection->Errors->Count > 0 )
@@ -78,7 +85,7 @@
         for ( long n = 0; n < nCount; n++ )
         {
             pErr = pConnection->Errors->GetItem( n );
-            printf( "Error #: %x\t%s\n", pErr->Number, (LPCSTR)pErr->Description );
+            printf( "[%s][%d][%s] ERROR: %x\t%s\n", pszFileName, nLine, pszFunction,
pErr->Number, (LPCSTR)pErr->Description );
         }
     }
 }
@@ -86,12 +93,12 @@
 /*!
     \brief  Print COM error.
 */
-void doPrintComError( _com_error &e )
+void doPrintComError( const char *pszFileName, int nLine, const char *pszFunction,
_com_error &e )
 {
     _bstr_t bstrSource( e.Source() );
     _bstr_t bstrDescription( e.Description() );
 
-    printf( "Error\n" );
+    printf( "[%s][%d][%s] ERROR:\n", pszFileName, nLine, pszFunction );
     printf( "\tCode = %08lx\n", e.Error() );
     wprintf( L"\tCode meaning = %s\n", e.ErrorMessage() );
     printf( "\tSource = %s\n", (LPCSTR)bstrSource );
@@ -139,8 +146,8 @@
     }
     catch ( _com_error &e )
     {
-        doPrintProviderError( pConnection );
-        doPrintComError( e );
+        doPrintProviderError( __FILE__, __LINE__, __FUNCTION__, pConnection );
+        doPrintComError( __FILE__, __LINE__, __FUNCTION__, e );
         return false;
     }
 
@@ -169,8 +176,8 @@
     }
     catch ( _com_error &e )
     {
-        doPrintProviderError( pConnection );
-        doPrintComError( e );
+        doPrintProviderError( __FILE__, __LINE__, __FUNCTION__, pConnection );
+        doPrintComError( __FILE__, __LINE__, __FUNCTION__, e );
         return false;
     }
 
@@ -190,7 +197,7 @@
             -----
             CREATE TABLE `tbAdo` 
             (
-              `bin` BINARY(50),
+              `bin` VARBINARY(1024),
               `txt` TEXT,
               `n` INTEGER,
               `vc` VARCHAR(50)
@@ -200,7 +207,7 @@
             -----
             CREATE TABLE `tbAdo` 
             (
-              `bin` BINARY(50),
+              `bin` VARBINARY(1024),
               `txt` TEXT,
               `n` INTEGER UNSIGNED,
               `vc` VARCHAR(50)
@@ -212,14 +219,15 @@
     _CommandPtr     pCommand            = NULL;
     _ParameterPtr   pParameter          = NULL;
     VARIANT         variant1;
+    VARIANT         variant2;
     VARIANT         variant3;
     VARIANT         variant4;
 
-    SAFEARRAY FAR * pArray;
-    SAFEARRAYBOUND  arrayBound[1];
+    SAFEARRAY FAR * pArrayBinary;
+    SAFEARRAYBOUND  arrayBoundBinary[1];
 
-    arrayBound[0].lLbound    = 0;
-    arrayBound[0].cElements  = nDataLen;
+    SAFEARRAY FAR * pArrayText;
+    SAFEARRAYBOUND  arrayBoundText[1];
 
     try
     {
@@ -230,21 +238,51 @@
         pCommand->CommandType = adCmdText;
 
         // BINARY
-        pArray = SafeArrayCreate( VT_UI1, 1, arrayBound );
-        for ( long n = 0; n < nDataLen; n++ )
         {
-            SafeArrayPutElement( pArray, &n, &(pData[n]) );
+            // init a SAFEARRAY
+            void *pSafeArrayDataRef = NULL;
+
+            arrayBoundBinary[0].lLbound    = 0;
+            arrayBoundBinary[0].cElements  = nDataLengthBinary;
+
+            pArrayBinary = SafeArrayCreate( VT_UI1, 1, arrayBoundBinary );
+
+            SafeArrayAccessData( pArrayBinary, &pSafeArrayDataRef );
+            memcpy( pSafeArrayDataRef, pDataBinary, nDataLengthBinary );
+            SafeArrayUnaccessData( pArrayBinary );
+
+            // init VARIANT with our safearray
+            variant1.vt     = VT_ARRAY|VT_UI1;
+            variant1.parray = pArrayBinary;
+
+            // init bound parameter with our variant
+            pParameter      = pCommand->CreateParameter( "bin", adBinary,
adParamInput, nDataLengthBinary, variant1 );
+            pCommand->Parameters->Append( pParameter );
         }
 
-        variant1.vt     = VT_ARRAY|VT_UI1;
-        variant1.parray = pArray;
-        pParameter      = pCommand->CreateParameter( "bin", adBinary, adParamInput,
nDataLen, variant1 );
-        pCommand->Parameters->Append( pParameter );
+        // TEXT
+        {
+            // init a SAFEARRAY
+            void *pSafeArrayDataRef = NULL;
 
-        // TEXT (we use same data as BINARY - because we can)
-        pParameter      = pCommand->CreateParameter( "txt", adChar, adParamInput,
nDataLen, variant1 );
-        pCommand->Parameters->Append( pParameter );
+            arrayBoundText[0].lLbound    = 0;
+            arrayBoundText[0].cElements  = nDataLengthText;
 
+            pArrayText = SafeArrayCreate( VT_UI1, 1, arrayBoundText );
+
+            SafeArrayAccessData( pArrayText, &pSafeArrayDataRef );
+            memcpy( pSafeArrayDataRef, pDataText, nDataLengthText );
+            SafeArrayUnaccessData( pArrayText );
+
+            // init VARIANT with our safearray
+            variant2.vt     = VT_ARRAY|VT_UI1;
+            variant2.parray = pArrayText;
+
+            // init bound parameter with our variant
+            pParameter      = pCommand->CreateParameter( "txt", adLongVarChar,
adParamInput, nDataLengthText, variant2 );
+            pCommand->Parameters->Append( pParameter );
+        }
+
         // INTEGER
         variant3.vt    = VT_I2;
         variant3.iVal  = 1867;
@@ -261,12 +299,11 @@
         pCommand->Execute( NULL, NULL, adCmdText ); 
 
 //        SafeArrayDestroy( variant4 );
-
     }
     catch ( _com_error &e )
     {
-        doPrintProviderError( pConnection );
-        doPrintComError( e );
+        doPrintProviderError( __FILE__, __LINE__, __FUNCTION__, pConnection );
+        doPrintComError( __FILE__, __LINE__, __FUNCTION__, e );
         return false;
     }
 
@@ -284,12 +321,12 @@
 
             MSSQL
             ------
-            CREATE PROCEDURE insAdo @bin BINARY(50), @txt TEXT, @n INT, @vc VARCHAR(50)
AS
+            CREATE PROCEDURE insAdo @bin VARBINARY(1024), @txt TEXT, @n INT, @vc
VARCHAR(50) AS
         	    INSERT INTO tbAdo VALUES( @bin, @txt, @n, @vc )
 
             MySQL
             -----
-            CREATE PROCEDURE `northwind`.`insAdo` ( IN bin BINARY(50), IN txt TEXT, IN n
INT, IN vc VARCHAR(50) )
+            CREATE PROCEDURE `northwind`.`insAdo` ( IN bin VARBINARY(1024), IN txt TEXT,
IN n INT, IN vc VARCHAR(50) )
             BEGIN
                  INSERT INTO tbAdo VALUES( @bin, @txt, @n, @vc );
             END
@@ -300,14 +337,15 @@
     _CommandPtr     pCommand            = NULL;
     _ParameterPtr   pParameter          = NULL;
     VARIANT         variant1;
+    VARIANT         variant2;
     VARIANT         variant3;
     VARIANT         variant4;
 
-    SAFEARRAY FAR * pArray;
-    SAFEARRAYBOUND  arrayBound[1];
+    SAFEARRAY FAR * pArrayBinary;
+    SAFEARRAYBOUND  arrayBoundBinary[1];
 
-    arrayBound[0].lLbound    = 0;
-    arrayBound[0].cElements  = nDataLen;
+    SAFEARRAY FAR * pArrayText;
+    SAFEARRAYBOUND  arrayBoundText[1];
 
     try
     {
@@ -318,21 +356,51 @@
         pCommand->CommandType = adCmdStoredProc;
 
         // BINARY
-        pArray = SafeArrayCreate( VT_UI1, 1, arrayBound );
-        for ( long n = 0; n < nDataLen; n++ )
         {
-            SafeArrayPutElement( pArray, &n, &(pData[n]) );
+            // init a SAFEARRAY
+            void *pSafeArrayDataRef = NULL;
+
+            arrayBoundBinary[0].lLbound    = 0;
+            arrayBoundBinary[0].cElements  = nDataLengthBinary;
+
+            pArrayBinary = SafeArrayCreate( VT_UI1, 1, arrayBoundBinary );
+
+            SafeArrayAccessData( pArrayBinary, &pSafeArrayDataRef );
+            memcpy( pSafeArrayDataRef, pDataBinary, nDataLengthBinary );
+            SafeArrayUnaccessData( pArrayBinary );
+
+            // init VARIANT with our safearray
+            variant1.vt     = VT_ARRAY|VT_UI1;
+            variant1.parray = pArrayBinary;
+
+            // init bound parameter with our variant
+            pParameter      = pCommand->CreateParameter( "bin", adBinary,
adParamInput, nDataLengthBinary, variant1 );
+            pCommand->Parameters->Append( pParameter );
         }
 
-        variant1.vt     = VT_ARRAY|VT_UI1;
-        variant1.parray = pArray;
-        pParameter      = pCommand->CreateParameter( "bin", adBinary, adParamInput,
nDataLen, variant1 );
-        pCommand->Parameters->Append( pParameter );
+        // TEXT
+        {
+            // init a SAFEARRAY
+            void *pSafeArrayDataRef = NULL;
 
-        // TEXT (we use same data as BINARY - because we can)
-        pParameter      = pCommand->CreateParameter( "txt", adChar, adParamInput,
nDataLen, variant1 );
-        pCommand->Parameters->Append( pParameter );
+            arrayBoundText[0].lLbound    = 0;
+            arrayBoundText[0].cElements  = nDataLengthText;
 
+            pArrayText = SafeArrayCreate( VT_UI1, 1, arrayBoundText );
+
+            SafeArrayAccessData( pArrayText, &pSafeArrayDataRef );
+            memcpy( pSafeArrayDataRef, pDataText, nDataLengthText );
+            SafeArrayUnaccessData( pArrayText );
+
+            // init VARIANT with our safearray
+            variant2.vt     = VT_ARRAY|VT_UI1;
+            variant2.parray = pArrayBinary;
+
+            // init bound parameter with our variant
+            pParameter      = pCommand->CreateParameter( "txt", adChar, adParamInput,
nDataLengthText, variant2 );
+            pCommand->Parameters->Append( pParameter );
+        }
+
         // INTEGER
         variant3.vt    = VT_I2;
         variant3.iVal  = 1867;
@@ -349,12 +417,11 @@
         pCommand->Execute( NULL, NULL, adCmdStoredProc ); 
 
 //        SafeArrayDestroy( variant4 );
-
     }
     catch ( _com_error &e )
     {
-        doPrintProviderError( pConnection );
-        doPrintComError( e );
+        doPrintProviderError( __FILE__, __LINE__, __FUNCTION__, pConnection );
+        doPrintComError( __FILE__, __LINE__, __FUNCTION__, e );
         return false;
     }
 
@@ -376,8 +443,8 @@
     }
     catch ( _com_error &e )
     {
-        doPrintProviderError( pConnection );
-        doPrintComError( e );
+        doPrintProviderError( __FILE__, __LINE__, __FUNCTION__, pConnection );
+        doPrintComError( __FILE__, __LINE__, __FUNCTION__, e );
         return false;
     }
 
@@ -385,6 +452,74 @@
 }
 
 /*!
+    \brief  Loads a file into memory.
+
+            Loads contents of file (pszFileName) into buffer (ppData).
+
+    \note
+            This takes care of allocating buffer at ppData but caller must
+            free it when done.
+
+    \param  pszFileName     File to be loaded. It must exist.
+    \param  ppData          Place to return the pointer to the file data. 
+    \param  pnDataLength    Place to return the number of bytes loaded from the 
+                            file. The buffer size at ppData may be this size OR
+                            larger.
+
+    \return bool
+
+    \retval false           Something went wrong. Error message was sent to stdout.
+    \retval true            Success.
+*/
+bool doLoadFile( const char *pszFileName, UCHAR **ppData, long *pnDataLength )
+{
+    bool bReturn = false;
+
+    int nFile = open( pszFileName, _O_RDONLY, _S_IREAD );
+    if ( nFile == -1 )
+    {
+        printf( "[%s][%d][%s] ERROR: Failed to open (%s)\n", __FILE__, __LINE__,
__FUNCTION__, pszFileName );
+        return false;
+    }
+
+    *pnDataLength = _filelength( nFile );
+    if ( *pnDataLength < 1 )
+    {
+        printf( "[%s][%d][%s] ERROR: Failed to get file length for (%s)\n", __FILE__,
__LINE__, __FUNCTION__, pszFileName );
+        goto doLoadFileExit1;
+    }
+
+    *ppData = (UCHAR*)malloc( *pnDataLength );
+    if ( *ppData == NULL )
+    {
+        printf( "[%s][%d][%s] ERROR: Failed to malloc %ld bytes\n", __FILE__, __LINE__,
__FUNCTION__, *pnDataLength );
+        goto doLoadFileExit2;
+    }
+
+    int nReadTotal  = 0;
+    int nRead       = 0;
+    do
+    {
+        nRead = read( nFile, *ppData, *pnDataLength );
+        nReadTotal += nRead;
+    } while ( nRead );
+
+    if ( (long)nReadTotal != *pnDataLength )
+        printf( "[%s][%d][%s] INFO: Allocated %ld and read %d into it.\n", __FILE__,
__LINE__, __FUNCTION__, *pnDataLength, nReadTotal );
+
+    bReturn = true;
+    goto doLoadFileExit1;
+
+doLoadFileExit2:
+    free( *ppData );
+
+doLoadFileExit1:
+    close( nFile );
+
+    return bReturn;
+}
+
+/*!
     \brief  main
 
             This is the 'main' entry point to this program - it all starts here.
@@ -399,10 +534,13 @@
     if ( FAILED( ::CoInitialize( NULL ) ) )
         return;
 
+    /* get some example binary data */
+    if ( !doLoadFile( BINARY_FILENAME, &pDataBinary, &nDataLengthBinary ) )
+        return;
+
     /* do it */
     if ( doConnect() )
     {
-        doSelect();
         doCreateParameterInsert();
         doCreateParameterProcedure();
         doSelect();

Thread
Connector/ODBC 5 commit: r457 - trunk/examples/CPP/7/ADOpharvey22 Jul