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/MYSQLPlusLib | pharvey | 22 Jun |