Modified:
trunk/MYSQLPlus/MYSQLPlusLib/MConnection.cpp
Log:
- added support for SQLBrowseConnect (still needs post-build tests)
Modified: trunk/MYSQLPlus/MYSQLPlusLib/MConnection.cpp
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MConnection.cpp 2006-08-11 04:12:32 UTC (rev 484)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MConnection.cpp 2006-08-11 09:31:11 UTC (rev 485)
@@ -1385,7 +1385,6 @@
*/
pDiagnostic->doClear();
-
/*!
\internal ODBC RULE (DM)
@@ -1400,7 +1399,7 @@
The value specified for argument StringLength1 was less than 0 and was not equal
to SQL_NTS.
*/
- if ( nStringLength1 < 0 && nStringLength1 != SQL_NTS) )
+ if ( nStringLength1 < 0 && nStringLength1 != SQL_NTS )
MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY090 ) );
/*!
@@ -1414,106 +1413,203 @@
/*!
\internal MYODBC RULE
- In this context - we need the following information to connect;
+ Its implied (by nBufferLength > 0) that we have a viable buffer to return
stuff in but we make sure
+ of this.
+ */
+ if ( !psOutConnectionString )
+ MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("Invalid buffer.") ) );
- - server
- - database
- - userid
- - password
+ /*!
+ \internal MYODBC RULE
+ In this context - we need the following attributes to connect;
+
+ - DSN || DRIVER
+ - SERVER
+ - UID
+ - PWD
+ - DATABASE
+
These are not strictly required but we ask for them all - favouring the idea of
discovering most common
- connection information.
+ connection information. The caller still has the option of providing the
attribute with no value. If the
+ value is required - the connect will fail.
*/
- /* */
- QString stringInConnection;
- QString stringOutConnection;
+ /* we will work with a MYODBCInsDataSource (even as we abuse the DRIVER attribute
within) because its so near perfect for this purpose */
+ MYODBCInsDataSource datasource;
- if ( psInConnectionString )
- stringInConnection.setUtf16( psInConnectionString, ( nNameLength1 == SQL_NTS ?
wcslen( psInConnectionString ) : nNameLength1 ) );
+ datasource.setMode( MYODBCInsDataSource::DATASOURCE_MODE_DSN_VIEW );
+ datasource.setScope( MYODBCInsDataSource::DATASOURCE_SCOPE_BOTH );
+ /* parse incoming attributes */
+ QString stringConnection;
+ QString stringConnectionMissing;
+
+ stringConnection.setUtf16( psInConnectionString, ( nStringLength1 == SQL_NTS ?
wcslen( psInConnectionString ) : nStringLength1 ) );
+
QHash<QString,QString> hashKeywordValues;
- if ( !MYODBCIns::getKeywordValues( &hashKeywordValues, stringInConnection,
MYODBCIns::DELIM_SEMI ) )
- MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
stringInConnection ) );
+ if ( !MYODBCIns::getKeywordValues( &hashKeywordValues, stringConnection,
MYODBCIns::DELIM_SEMI ) )
+ MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
stringConnection ) );
+ /*!
+ \internal ODBC RULE
- /* if we have a DSN then look it up... */
- MYODBCInsDataSource datasource;
+ When SQLBrowseConnect is called for the first time on a connection, the browse
request connection string
+ must contain the DSN keyword or the DRIVER keyword.
+ */
+ if ( hashKeywordValues.contains( "DSN" ) )
+ {
+ /*!
+ \internal ODBC RULE (DM)
- datasource.setMode( MYODBCInsDataSource::DATASOURCE_MODE_DSN_VIEW );
- datasource.setScope( MYODBCInsDataSource::DATASOURCE_SCOPE_BOTH );
+ The attribute value for the DSN keyword was longer than SQL_MAX_DSN_LENGTH
characters.
+ */
+ if ( hashKeywordValues.value( "DSN" ).length() > SQL_MAX_DSN_LENGTH )
+ MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_IM010 ) );
- if ( !hashKeywordValues.contains( "DSN" ) )
+ /*!
+ \internal ODBC RULE (me thinks)
+
+ We use any DSN attributes we can find in the system information - but the
ones provided in hashKeywordValues
+ will take precedence.
+
+ \note
+
+ We ignore any error in loading the DSN - it does not make sense to return
DIA_IM002 in this context as we are
+ driver to be used.
+ */
+ datasource.doRead( hashKeywordValues.value( "DSN" ) );
+ }
+ else if ( hashKeywordValues.contains( "DRIVER" ) )
{
- if ( !datasource.doRead( hashKeywordValues.value( "DSN" ) ) )
- MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_IM002 ) );
+ /*!
+ \internal ODBC RULE (DM)
+
+ The attribute value for the DRIVER keyword was longer than 255 characters.
+ */
+ if ( hashKeywordValues.value( "DRIVER" ).length() > 255 )
+ MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_IM011 ) );
}
+ else
+ MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0, tr("DSN
or DRIVER attribute must be supplied.") ) );
- if ( !hashKeywordValues.contains( "DSN" ) )
+ /*!
+ \internal ODBC RULE
+
+ An invalid attribute keyword was specified in the browse request connection
string
+ (InConnectionString). (Function returns SQL_NEED_DATA.)
+
+ \note
+
+ The concern here is that the caller will not take steps to handle this case and
end up
+ looping on SQL_NEED_DATA.
+ */
+ if ( !datasource.setAttributes( hashKeywordValues, true, false ) )
{
- if ( !datasource.doRead( hashKeywordValues.value( "DSN" ) ) )
- MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_IM002 ) );
+ /* getDiagnostic()->doAppend( MDiagnostic::DIA_01S00 ); */
+ /* nReturn = SQL_NEED_DATA; */
+ MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("Failed to validate the attributes.") ) );
}
/* do we have a SERVER attribute? */
if ( !hashKeywordValues.contains( "SERVER" ) )
- stringOutConnection = "SERVER:" + tr("Server") + "=?";
+ stringConnectionMissing = "SERVER:" + tr("Server") + "=?";
/* do we have a UID attribute? */
if ( !hashKeywordValues.contains( "UID" ) )
{
- if ( !stringOutConnection.isEmpty() )
- stringOutConnection += ";";
- stringOutConnection = "UID:" + tr("User ID") + "=?";
+ if ( !stringConnectionMissing.isEmpty() )
+ stringConnectionMissing += ";";
+ stringConnectionMissing = "UID:" + tr("User ID") + "=?";
}
/* do we have a PWD attribute? */
if ( !hashKeywordValues.contains( "PWD" ) )
{
- if ( !stringOutConnection.isEmpty() )
- stringOutConnection += ";";
- stringOutConnection = "PWD:" + tr("Password") + "=?";
+ if ( !stringConnectionMissing.isEmpty() )
+ stringConnectionMissing += ";";
+ stringConnectionMissing = "PWD:" + tr("Password") + "=?";
}
/* do we have a DATABASE attribute? */
if ( !hashKeywordValues.contains( "DATABASE" ) )
{
- if ( !stringOutConnection.isEmpty() )
- stringOutConnection += ";";
+ if ( !stringConnectionMissing.isEmpty() )
+ stringConnectionMissing += ";";
/*!
\internal
\todo
We should connect with SERVER+UID+PWD and get list of databases. In which
case we should use a list
of databases surrounded by curly braces - instead of ?.
+
+ For example; "DATABASE:Database={mysql,test}"
*/
- stringOutConnection = "DATABASE:" + tr("Database") + "=?";
+ stringConnectionMissing = "DATABASE:" + tr("Database") + "=?";
}
+ /* are we missing mandatory attributes? */
+ if ( !stringConnectionMissing.isEmpty() )
+ {
+ /*!
+ \internal ODBC RULE
+ Each call to SQLBrowseConnect() returns only the information required to
satisfy the next level of
+ the connection process. DB2 CLI associates state information with the
connection handle so that the
+ context can always be determined on each call.
+ */
+ /*!
+ \internal ODBC RULE
-+++++++++
- SQLRETURN nReturn = SQL_SUCCESS;
+ The buffer *OutConnectionString was not large enough to return the entire
browse result
+ connection string, so the string was truncated. The buffer *StringLength2Ptr
contains
+ the length of the untruncated browse result connection string. (Function
returns
+ SQL_SUCCESS_WITH_INFO.)
- if ( !stringOutConnection.isEmpty() )
- {
+ \note
+
+ The caller must NOT assume that SQL_SUCCESS_WITH_INFO means we can proceed.
In this case we will
+ return SQL_SUCCESS_WITH_INFO and the caller must check that the length in
pnStringLength2Ptr is
+ not larger than nBufferLength.
+
+ \internal MYODBC RULE
+
+ We will return an error if pnStringLength2Ptr is not provided and we get a
truncation as it is
+ likely that the caller will catch the truncation (it would have to get our
state info to see
+ that we are, in fact, still wanting more data - STATE_C3).
+ */
+ SQLRETURN nReturn = SQL_NEED_DATA;
+
+ if ( !MYODBCC::doStringCopyOut( psOutConnectionString, nBufferLength /
sizeof(SQLWCHAR), (SQLWCHAR*)stringConnectionMissing.utf16(),
(SQLINTEGER*)pnStringLength2Ptr ) )
+ {
+ if ( !pnStringLength2Ptr )
+ {
+ MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("Output buffer too small and length indicator buffer not provided.") ) );
+ }
+ else
+ nReturn = SQL_SUCCESS_WITH_INFO;
+ }
+
+ /* we want more data - regardless of the return value */
setState( STATE_C3 );
- nReturn = SQL_NEED_DATA;
+ MYODBCDbgReturn( nReturn );
}
- else
- {
- }
/*!
+ \internal
+ \note
+
+ We want to be able to return SQL_SUCCESS_WITH_INFO without indicating a
truncation.
+ */
+ if ( pnStringLength2Ptr )
+ *pnStringLength2Ptr = 0;
+
+ /*!
\internal ODBC RULE
- The buffer *OutConnectionString was not large enough to return the entire browse
result
- connection string, so the string was truncated. The buffer *StringLength2Ptr
contains
- the length of the untruncated browse result connection string. (Function returns
- SQL_SUCCESS_WITH_INFO.)
+ The driver was unable to establish a connection with the data source.
*/
- psOutConnectionString;
- nBufferLength;
- pnStringLength2Ptr;
+ if ( doConnectInternal( &datasource ) != SQL_SUCCESS )
+ MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_08001 ) );
- MYODBCDbgReturn( nReturn );
+ MYODBCDbgReturn( SQL_SUCCESS );
}
SQLRETURN MConnection::doConnect( SQLWCHAR *psServerName, SQLSMALLINT nNameLength1,
SQLWCHAR *psUserName, SQLSMALLINT nNameLength2, SQLWCHAR *psAuthentication, SQLSMALLINT
nNameLength3 )
| Thread |
|---|
| • Connector/ODBC 5 commit: r485 - trunk/MYSQLPlus/MYSQLPlusLib | pharvey | 11 Aug |