List:Commits« Previous MessageNext Message »
From:pharvey Date:June 22 2006 9:53pm
Subject:Connector/ODBC 5 commit: r363 - in trunk: MYODBCDriver/MYODBCDriverLib MYSQLPlus/MYSQLPlusLib
View as plain text  
Modified:
   trunk/MYODBCDriver/MYODBCDriverLib/SQLDriverConnectW.cpp
   trunk/MYODBCDriver/MYODBCDriverLib/SQLGetFunctions.cpp
   trunk/MYSQLPlus/MYSQLPlusLib/MConnection.cpp
Log:
Getting ready to morph older SQLDriverConnect code into our sparkling new stuff.

Modified: trunk/MYODBCDriver/MYODBCDriverLib/SQLDriverConnectW.cpp
===================================================================
--- trunk/MYODBCDriver/MYODBCDriverLib/SQLDriverConnectW.cpp	2006-06-22 21:30:26 UTC (rev
362)
+++ trunk/MYODBCDriver/MYODBCDriverLib/SQLDriverConnectW.cpp	2006-06-22 21:53:20 UTC (rev
363)
@@ -8,6 +8,35 @@
 */
 #include "MYODBCDriverInternal.h"
 
+/*!
+    \brief  <B>ODBC 1.0 API</B>
+            <BR>
+            Is an alternative to SQLConnect. It supports data sources that
+            require more connection information than the three arguments in
+            SQLConnect, dialog boxes to prompt the user for all connection
+            information, and data sources that are not defined in the
+            system information.
+
+    \param  hDbc
+    \param  hWnd
+    \param  pszInConnectionString
+    \param  nStringLength1
+    \param  pszOutConnectionString
+    \param  nBufferLength
+    \param  pnStringLength2Ptr
+    \param  nDriverCompletion
+
+    \return SQLRETURN
+
+    \retval SQL_SUCCESS             Request processed ok.
+    \retval SQL_SUCCESS_WITH_INFO   Request was probably processed ok - check diagnostic.
+    \retval SQL_NO_DATA             
+    \retval SQL_ERROR               Request failed.
+    \retval SQL_INVALID_HANDLE      Invalid handle was provided.
+
+    \sa     SQLConnect
+            SQLBrowseConnect
+*/
 SQLRETURN SQL_API SQLDriverConnectW( SQLHDBC         hDbc,
                                      SQLHWND         hWnd,
                                      SQLWCHAR *      psInConnectionString,

Modified: trunk/MYODBCDriver/MYODBCDriverLib/SQLGetFunctions.cpp
===================================================================
--- trunk/MYODBCDriver/MYODBCDriverLib/SQLGetFunctions.cpp	2006-06-22 21:30:26 UTC (rev
362)
+++ trunk/MYODBCDriver/MYODBCDriverLib/SQLGetFunctions.cpp	2006-06-22 21:53:20 UTC (rev
363)
@@ -74,12 +74,12 @@
 /*  SQL_API_SQLTRANSACT,            */
 /*  SQL_API_SQLALLOCHANDLESTD       */
 /*  SQL_API_SQLBULKOPERATIONS,      */
-    SQL_API_SQLBINDPARAMETER
+    SQL_API_SQLBINDPARAMETER,
 /*  SQL_API_SQLBROWSECONNECT,       */
 /*  SQL_API_SQLCOLATTRIBUTES,       */
 /*  SQL_API_SQLCOLUMNPRIVILEGES,    */
 /*  SQL_API_SQLDESCRIBEPARAM,       */
-/*  SQL_API_SQLDRIVERCONNECT,       */
+    SQL_API_SQLDRIVERCONNECT,
 /*  SQL_API_SQLDRIVERS,             */
 /*  SQL_API_SQLEXTENDEDFETCH,       */
 /*  SQL_API_SQLFOREIGNKEYS,         */

Modified: trunk/MYSQLPlus/MYSQLPlusLib/MConnection.cpp
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MConnection.cpp	2006-06-22 21:30:26 UTC (rev 362)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MConnection.cpp	2006-06-22 21:53:20 UTC (rev 363)
@@ -1988,7 +1988,276 @@
 
     pDiagnostic->doClear();
 
-    MYODBCDbgReturn( SQL_ERROR );
+    /*!
+        \internal ODBC RULE (DM)
+
+        The specified ConnectionHandle had already been used to establish a 
+        connection with a data source, and the connection was still open or 
+        the user was browsing for a connection.
+
+        \note
+
+        Normally a DM thing but we also handle here for case when app linked
+        directly to driver.
+    */
+    if ( getState() != STATE_C2 )
+        MYODBCDbgReturn( MYODBCDiaAppend( pDbc->hDia, MYODBC_DIA_08002, 0, NULL ) );
+
+    MYODBC_INS_DATASOURCE * pDataSource = MYODBCInsAllocDataSource(
MYODBC_INS_DATASOURCE_MODE_DRIVER_CONNECT );
+    MYODBC_INS_DRIVER *     pDriver     = MYODBCInsAllocDriver();      /* we have to read
in driver info to get setup lib */
+    SQLRETURN               nReturn     = SQL_SUCCESS;
+    MYODBC_C_BOOL           bPrompt     = MYODBC_C_FALSE;
+    char                    szError[1024];
+    MYODBC_C_DLL            hModule     = NULL;
+
+    /* parse incoming string */
+    if ( !MYODBCInsReadConnectStr( pDataSource, (LPCSTR)pszInConnectionString ) )
+    {
+        nReturn = MYODBCDiaAppend( pDbc->hDia, MYODBC_DIA_HY000, 0, "Failed to parse
the incoming connect string." );
+        goto MYODBCDrvDriverConnectExit1;
+    }
+
+    /*!
+        \internal ODBC Rule
+
+        If the connection string contains the DSN keyword, the driver 
+        retrieves the information for the specified data source (and
+        merges it into given connection info with given connection info
+        having precedence).
+
+        \note
+                This also allows us to get pszDRIVER (if not already given).
+    */    
+    if ( pDataSource->pszDSN )
+    {
+        if ( !MYODBCInsReadDataSource( pDataSource, pDataSource->pszDSN ) )
+        {
+            /*!
+                \internal ODBC Rule
+
+                Establish a connection to a data source that is not defined in the system

+                information. If the application supplies a partial connection string, the

+                driver can prompt the user for connection information.
+            */    
+        }
+    }
+
+    /* 
+        Make pDataSource good for mysql_real_connect(). Mostly
+        means making some "" values NULL.
+    */
+    MYODBCInsDefaultDataSource( pDataSource );
+
+    /*!
+       \internal MYODBC Rule
+
+       We can not present a prompt unless we can lookup the name of the 
+       setup library file name. This means we need a DRIVER. We try to xref
+       using a DSN (above) or, hopefully, get one in connection string.
+
+       \note 
+
+       This will, when we need to prompt, trump the ODBC rule where we can 
+       connect with a DSN which does not exist. A possible solution is to
+       hard-code some fall-back value for pDataSource->pszDRIVER but lets 
+       not do it until we see if this is a problem in practice. After all;
+       if the DSN does not exist the app can at least provide the driver
+       name for us in the connection string.
+    */
+    if ( !pDataSource->pszDRIVER && nDriverCompletion != SQL_DRIVER_NOPROMPT )
+    {
+        sprintf( szError, "Need driver name to lookup setup library. DSN=(%s)\n",
pDataSource->pszDSN );
+        nReturn = MYODBCDiaAppend( pDbc->hDia, MYODBC_DIA_HY000, 0, szError );
+        goto MYODBCDrvDriverConnectExit1;
+    }
+
+    /*!
+       \internal ODBC Rule
+
+       We can not present a prompt if we have a null window handle.
+    */
+    if ( !hWnd && nDriverCompletion != SQL_DRIVER_NOPROMPT )
+    {
+        nReturn = MYODBCDiaAppend( pDbc->hDia, MYODBC_DIA_IM008, 0, "Invalid window
handle for connection completion argument." );
+        goto MYODBCDrvDriverConnectExit1;
+    }
+
+    /*!
+        \internal ODBC Rule
+
+        We only prompt if we need to. 
+
+        Not so obvious gray area is with
(SQL_DRIVER_COMPLETE/SQL_DRIVER_COMPLETE_REQUIRED)
+        server and password - particularly password. These can work with defaults/blank
but 
+        many callers expect prompting when these are blank. So we compromise; we try to 
+        connect and if it works we say its ok otherwise we go to a prompt.
+    */    
+    switch ( nDriverCompletion )
+    {
+        case SQL_DRIVER_PROMPT:
+            pDataSource->nPrompt= MYODBC_INS_DATASOURCE_PROMPT_PROMPT;
+            bPrompt             = MYODBC_C_TRUE;
+            break;
+
+        case SQL_DRIVER_COMPLETE:
+            pDataSource->nPrompt = MYODBC_INS_DATASOURCE_PROMPT_COMPLETE;
+            if ( MYODBCDrvConnect( pDbc, pDataSource ) == SQL_SUCCESS )
+                goto MYODBCDrvDriverConnectExit3;
+            bPrompt = MYODBC_C_TRUE;
+            break;
+
+        case SQL_DRIVER_COMPLETE_REQUIRED:
+            pDataSource->nPrompt = MYODBC_INS_DATASOURCE_PROMPT_REQUIRED;
+            if ( MYODBCDrvConnect( pDbc, pDataSource ) == SQL_SUCCESS )
+                goto MYODBCDrvDriverConnectExit3;
+            bPrompt = MYODBC_C_TRUE;
+            break;
+
+        case SQL_DRIVER_NOPROMPT:
+            pDataSource->nPrompt = MYODBC_INS_DATASOURCE_PROMPT_NOPROMPT;
+            /*!
+               \internal ODBC Rule
+
+               We need a DSN or DRIVER in order to work without prompting.
+            */    
+            if ( !pDataSource->pszDSN && !pDataSource->pszDRIVER )
+            {
+                nReturn = MYODBCDiaAppend( pDbc->hDia, MYODBC_DIA_IM007, 0, "Missing
DSN and/or DRIVER and SQL_DRIVER_NOPROMPT." );
+                goto MYODBCDrvDriverConnectExit1;
+            }
+            break;
+        default:
+            {
+                nReturn = MYODBCDiaAppend( pDbc->hDia, MYODBC_DIA_HY110, 0, "Invalid
driver completion." );
+                goto MYODBCDrvDriverConnectExit1;
+            }
+    }
+
+    if ( bPrompt )
+    {
+        BOOL (*pFunc)( SQLHDBC, SQLHWND, MYODBC_INS_DATASOURCE * );
+
+        /* 
+           At this point we should have a driver name (friendly name) either loaded
+           from DSN or provided in connection string. So lets determine the setup
+           library file name (better to not assume name). We read from ODBC system 
+           info. This allows someone to configure for a custom setup interface.
+        */
+        if ( !MYODBCInsReadDriver( pDriver, pDataSource->pszDRIVER ) )
+        {
+            sprintf( szError, "Could not find driver %s in system information.",
pDataSource->pszDRIVER );
+            nReturn = MYODBCDiaAppend( pDbc->hDia, MYODBC_DIA_HY000, 0, szError );
+            goto MYODBCDrvDriverConnectExit1;
+        }
+
+        if ( !pDriver->pszSETUP )
+        {
+            nReturn = MYODBCDiaAppend( pDbc->hDia, MYODBC_DIA_HY000, 0, "Could not
determine the file name of setup library." );
+            goto MYODBCDrvDriverConnectExit1;
+        }
+
+        /*
+           We dynamically load setup lib to avoid introducing gui link dependencies 
+           into driver and also allowing the setup library to be pluggable. So 
+           a ncurses ver or a gtk ver etc could be created/used and this code is ok.
+        */
+        MYODBCCInitLibrary();
+        if ( !(hModule = MYODBCCLoadLibrary( pDriver->pszSETUP )) )
+        {
+            nReturn = MYODBCDiaAppend( pDbc->hDia, MYODBC_DIA_HY000, 0, "Could not
load the setup library." );
+            goto MYODBCDrvDriverConnectExit1;
+        }
+        /*
+           The setup library should expose a MYODBCSetupDriverConnect() C entry point
+           for us to call.
+        */
+        pFunc = (BOOL (*)( SQLHDBC, SQLHWND, MYODBC_INS_DATASOURCE * ))
MYODBCCGetProcAddress( hModule, "MYODBCSetupDriverConnect" );
+        if ( pFunc == NULL )
+        {
+#ifdef WIN32
+            LPVOID pszMsg;
+
+            FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+                          NULL,
+                          GetLastError(),
+                          MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                          (LPTSTR) &pszMsg,
+                          0, 
+                          NULL );
+            MYODBCCfprintf( stderr, pszMsg );
+            nReturn = MYODBCDiaAppend( pDbc->hDia, MYODBC_DIA_HY000, 0, pszMsg );
+            LocalFree( pszMsg );
+#else
+            nReturn = MYODBCDiaAppend( pDbc->hDia, MYODBC_DIA_HY000, 0, "Could not
find MYODBCSetupDriverConnect in setup library." );
+#endif
+            goto MYODBCDrvDriverConnectExit2;
+        }
+
+        /*
+           Prompt. Function returns false if user cancels.
+        */
+        if ( !pFunc( pDbc, hWnd, pDataSource ) )
+        {
+            nReturn = MYODBCDiaAppend( pDbc->hDia, MYODBC_DIA_HY000, 0, "User
cancelled." );
+            goto MYODBCDrvDriverConnectExit2;
+        }
+    } /* if prompt */
+
+    /* lordy tunderin by - we finally get here! */
+    if ( (nReturn = MYODBCDrvConnect( pDbc, pDataSource )) != SQL_SUCCESS )
+        goto MYODBCDrvDriverConnectExit2;
+
+MYODBCDrvDriverConnectExit3:
+    pDbc->attr_current_catalog  = MYODBCCStrDup( pDataSource->pszDATABASE, SQL_NTS
);
+    pDbc->nFlag                 = atol( pDataSource->pszOPTION );
+    pDbc->nPort                 = atoi( pDataSource->pszPORT );
+    pDbc->pszDataSourceName     = MYODBCCStrDup( pDataSource->pszDSN, SQL_NTS );
+    pDbc->pszPassword           = MYODBCCStrDup( pDataSource->pszPASSWORD, SQL_NTS
);
+    pDbc->pszServer             = MYODBCCStrDup( pDataSource->pszSERVER, SQL_NTS );
+    pDbc->pszUser               = MYODBCCStrDup( pDataSource->pszUSER, SQL_NTS );
+    MYODBCDrvSetDbcState( pDbc, MYODBC_DRV_STATE_C4 );
+
+    /*! 
+        \internal ODBC Rule
+
+        Create a return connection string only if we connect. pszOutConnectionString
'should' 
+        have at least 1024 bytes allocated or be null.
+    */
+    if ( pszOutConnectionString )
+    {
+#ifdef WIN32
+        /*!
+            \internal MYODBC Rule
+
+            Do nothing special if in-str and out-str are same address. This is because
+            ADO/VB will do this while at the same time *not* provide the space
+            recommended by the ODBC specification (1024 bytes min) resulting in a
+            "Catastrophic error" - the driver going bye bye.
+        */        
+        if ( pszOutConnectionString != pszInConnectionString )
+#endif
+        {
+            *pszOutConnectionString = '\0';
+            if ( !MYODBCInsWriteConnectStr( pDataSource, (char *)pszOutConnectionString,
nBufferLength ) )
+            {
+                MYODBCDiaAppend( pDbc->hDia, MYODBC_DIA_01000, 0, "Something went
wrong while building the outgoing connect string." );
+                nReturn = SQL_SUCCESS_WITH_INFO;
+            }
+        }
+
+        if ( pnStringLength2Ptr )
+            *pnStringLength2Ptr = strlen( pszOutConnectionString );
+    }
+
+MYODBCDrvDriverConnectExit2:
+    if ( hModule )
+        MYODBCCFreeLibrary( hModule );
+
+MYODBCDrvDriverConnectExit1:
+    MYODBCInsFreeDriver( pDriver );
+    MYODBCInsFreeDataSource( pDataSource );
+
+    MYODBCDbgReturn( nReturn );
 }
 
 SQLRETURN MConnection::doEndTran( SQLSMALLINT nCompletionType )

Thread
Connector/ODBC 5 commit: r363 - in trunk: MYODBCDriver/MYODBCDriverLib MYSQLPlus/MYSQLPlusLibpharvey22 Jun