+ if ((retcode != SQL_SUCCESS) &&
+ (retcode != SQL_SUCCESS_WITH_INFO))
+ return(DispAllErrors(henv, hdbc));
+
+ outConnectBuffer[outConnectBufferLen] = 0;
+ outConnectionStr = outConnectBuffer;
+ dbOpenedWithConnectionString = true;
+
+ return open(failOnDataTypeUnsupported);
+}
+
+/********** wxDb::Open() **********/
+bool wxDb::Open(const wxString &Dsn, const wxString &Uid, const wxString &AuthStr, bool failOnDataTypeUnsupported)
+{
+ wxASSERT(Dsn.Length());
+ dsn = Dsn;
+ uid = Uid;
+ authStr = AuthStr;
+
+ inConnectionStr = wxT("");
+ outConnectionStr = wxT("");
+
+ RETCODE retcode;
+
+ if (!FwdOnlyCursors())
+ {
+ // Specify that the ODBC cursor library be used, if needed. This must be
+ // specified before the connection is made.
+ retcode = SQLSetConnectOption(hdbc, SQL_ODBC_CURSORS, SQL_CUR_USE_IF_NEEDED);
+
+#ifdef DBDEBUG_CONSOLE
+ if (retcode == SQL_SUCCESS)
+ cout << wxT("SQLSetConnectOption(CURSOR_LIB) successful") << endl;
+ else
+ cout << wxT("SQLSetConnectOption(CURSOR_LIB) failed") << endl;
+#else
+ wxUnusedVar( retcode );
+#endif
+ }
+
+ // Connect to the data source
+ retcode = SQLConnect(hdbc, (SQLTCHAR FAR *) dsn.c_str(), SQL_NTS,
+ (SQLTCHAR FAR *) uid.c_str(), SQL_NTS,
+ (SQLTCHAR FAR *) authStr.c_str(), SQL_NTS);
+
+ if ((retcode != SQL_SUCCESS) &&
+ (retcode != SQL_SUCCESS_WITH_INFO))
+ return(DispAllErrors(henv, hdbc));
+
+ return open(failOnDataTypeUnsupported);
+
+} // wxDb::Open()
+
+
+bool wxDb::Open(wxDbConnectInf *dbConnectInf, bool failOnDataTypeUnsupported)
+{
+ wxASSERT(dbConnectInf);
+
+ // Use the connection string if one is present
+ if (dbConnectInf->UseConnectionStr())
+ return Open(GetConnectionInStr(), failOnDataTypeUnsupported);
+ else
+ return Open(dbConnectInf->GetDsn(), dbConnectInf->GetUserID(),
+ dbConnectInf->GetPassword(), failOnDataTypeUnsupported);
+} // wxDb::Open()
+
+
+bool wxDb::Open(wxDb *copyDb)
+{
+ dsn = copyDb->GetDatasourceName();
+ uid = copyDb->GetUsername();
+ authStr = copyDb->GetPassword();
+ inConnectionStr = copyDb->GetConnectionInStr();
+ outConnectionStr = copyDb->GetConnectionOutStr();
+
+ RETCODE retcode;
+
+ if (!FwdOnlyCursors())
+ {
+ // Specify that the ODBC cursor library be used, if needed. This must be
+ // specified before the connection is made.
+ retcode = SQLSetConnectOption(hdbc, SQL_ODBC_CURSORS, SQL_CUR_USE_IF_NEEDED);
+
+#ifdef DBDEBUG_CONSOLE
+ if (retcode == SQL_SUCCESS)
+ cout << wxT("SQLSetConnectOption(CURSOR_LIB) successful") << endl;
+ else
+ cout << wxT("SQLSetConnectOption(CURSOR_LIB) failed") << endl;
+#else
+ wxUnusedVar( retcode );
+#endif
+ }
+
+ if (copyDb->OpenedWithConnectionString())
+ {
+ // Connect to the data source
+ SQLTCHAR outConnectBuffer[SQL_MAX_CONNECTSTR_LEN+1];
+ short outConnectBufferLen;
+
+ inConnectionStr = copyDb->GetConnectionInStr();
+
+ retcode = SQLDriverConnect(hdbc, NULL, (SQLTCHAR FAR *)inConnectionStr.c_str(),
+ inConnectionStr.Length(), (SQLTCHAR FAR *)outConnectBuffer,
+ sizeof(outConnectBuffer), &outConnectBufferLen, SQL_DRIVER_COMPLETE);
+
+ if ((retcode != SQL_SUCCESS) &&
+ (retcode != SQL_SUCCESS_WITH_INFO))
+ return(DispAllErrors(henv, hdbc));
+
+ outConnectBuffer[outConnectBufferLen] = 0;
+ outConnectionStr = outConnectBuffer;
+ dbOpenedWithConnectionString = true;
+ }
+ else
+ {
+ // Connect to the data source
+ retcode = SQLConnect(hdbc, (SQLTCHAR FAR *) dsn.c_str(), SQL_NTS,
+ (SQLTCHAR FAR *) uid.c_str(), SQL_NTS,
+ (SQLTCHAR FAR *) authStr.c_str(), SQL_NTS);
+ }
+
+ if ((retcode != SQL_SUCCESS) &&
+ (retcode != SQL_SUCCESS_WITH_INFO))
+ return(DispAllErrors(henv, hdbc));
+
+/*
+ If using Intersolv branded ODBC drivers, this is the place where you would substitute
+ your branded driver license information
+
+ SQLSetConnectOption(hdbc, 1041, (UDWORD) wxEmptyString);
+ SQLSetConnectOption(hdbc, 1042, (UDWORD) wxEmptyString);
+*/
+
+ // Mark database as open
+ dbIsOpen = true;
+
+ // Allocate a statement handle for the database connection
+ if (SQLAllocStmt(hdbc, &hstmt) != SQL_SUCCESS)
+ return(DispAllErrors(henv, hdbc));
+
+ // Set Connection Options
+ if (!setConnectionOptions())
+ return false;
+
+ // Instead of Querying the data source for info about itself, it can just be copied
+ // from the wxDb instance that was passed in (copyDb).
+ wxStrcpy(dbInf.serverName,copyDb->dbInf.serverName);
+ wxStrcpy(dbInf.databaseName,copyDb->dbInf.databaseName);
+ wxStrcpy(dbInf.dbmsName,copyDb->dbInf.dbmsName);
+ wxStrcpy(dbInf.dbmsVer,copyDb->dbInf.dbmsVer);
+ dbInf.maxConnections = copyDb->dbInf.maxConnections;
+ dbInf.maxStmts = copyDb->dbInf.maxStmts;
+ wxStrcpy(dbInf.driverName,copyDb->dbInf.driverName);
+ wxStrcpy(dbInf.odbcVer,copyDb->dbInf.odbcVer);
+ wxStrcpy(dbInf.drvMgrOdbcVer,copyDb->dbInf.drvMgrOdbcVer);
+ wxStrcpy(dbInf.driverVer,copyDb->dbInf.driverVer);
+ dbInf.apiConfLvl = copyDb->dbInf.apiConfLvl;
+ dbInf.cliConfLvl = copyDb->dbInf.cliConfLvl;
+ dbInf.sqlConfLvl = copyDb->dbInf.sqlConfLvl;
+ wxStrcpy(dbInf.outerJoins,copyDb->dbInf.outerJoins);
+ wxStrcpy(dbInf.procedureSupport,copyDb->dbInf.procedureSupport);
+ wxStrcpy(dbInf.accessibleTables,copyDb->dbInf.accessibleTables);
+ dbInf.cursorCommitBehavior = copyDb->dbInf.cursorCommitBehavior;
+ dbInf.cursorRollbackBehavior = copyDb->dbInf.cursorRollbackBehavior;
+ dbInf.supportNotNullClause = copyDb->dbInf.supportNotNullClause;
+ wxStrcpy(dbInf.supportIEF,copyDb->dbInf.supportIEF);
+ dbInf.txnIsolation = copyDb->dbInf.txnIsolation;
+ dbInf.txnIsolationOptions = copyDb->dbInf.txnIsolationOptions;
+ dbInf.fetchDirections = copyDb->dbInf.fetchDirections;
+ dbInf.lockTypes = copyDb->dbInf.lockTypes;
+ dbInf.posOperations = copyDb->dbInf.posOperations;
+ dbInf.posStmts = copyDb->dbInf.posStmts;
+ dbInf.scrollConcurrency = copyDb->dbInf.scrollConcurrency;
+ dbInf.scrollOptions = copyDb->dbInf.scrollOptions;
+ dbInf.staticSensitivity = copyDb->dbInf.staticSensitivity;
+ dbInf.txnCapable = copyDb->dbInf.txnCapable;
+ dbInf.loginTimeout = copyDb->dbInf.loginTimeout;
+
+ // VARCHAR = Variable length character string
+ typeInfVarchar.FsqlType = copyDb->typeInfVarchar.FsqlType;
+ typeInfVarchar.TypeName = copyDb->typeInfVarchar.TypeName;
+ typeInfVarchar.Precision = copyDb->typeInfVarchar.Precision;
+ typeInfVarchar.CaseSensitive = copyDb->typeInfVarchar.CaseSensitive;
+ typeInfVarchar.MaximumScale = copyDb->typeInfVarchar.MaximumScale;
+
+ // Float
+ typeInfFloat.FsqlType = copyDb->typeInfFloat.FsqlType;
+ typeInfFloat.TypeName = copyDb->typeInfFloat.TypeName;
+ typeInfFloat.Precision = copyDb->typeInfFloat.Precision;
+ typeInfFloat.CaseSensitive = copyDb->typeInfFloat.CaseSensitive;
+ typeInfFloat.MaximumScale = copyDb->typeInfFloat.MaximumScale;
+
+ // Integer
+ typeInfInteger.FsqlType = copyDb->typeInfInteger.FsqlType;
+ typeInfInteger.TypeName = copyDb->typeInfInteger.TypeName;
+ typeInfInteger.Precision = copyDb->typeInfInteger.Precision;
+ typeInfInteger.CaseSensitive = copyDb->typeInfInteger.CaseSensitive;
+ typeInfInteger.MaximumScale = copyDb->typeInfInteger.MaximumScale;
+
+ // Date/Time
+ typeInfDate.FsqlType = copyDb->typeInfDate.FsqlType;
+ typeInfDate.TypeName = copyDb->typeInfDate.TypeName;
+ typeInfDate.Precision = copyDb->typeInfDate.Precision;
+ typeInfDate.CaseSensitive = copyDb->typeInfDate.CaseSensitive;
+ typeInfDate.MaximumScale = copyDb->typeInfDate.MaximumScale;
+
+ // Blob
+ typeInfBlob.FsqlType = copyDb->typeInfBlob.FsqlType;
+ typeInfBlob.TypeName = copyDb->typeInfBlob.TypeName;
+ typeInfBlob.Precision = copyDb->typeInfBlob.Precision;
+ typeInfBlob.CaseSensitive = copyDb->typeInfBlob.CaseSensitive;
+ typeInfBlob.MaximumScale = copyDb->typeInfBlob.MaximumScale;
+
+#ifdef DBDEBUG_CONSOLE
+ cout << wxT("VARCHAR DATA TYPE: ") << typeInfVarchar.TypeName << endl;
+ cout << wxT("INTEGER DATA TYPE: ") << typeInfInteger.TypeName << endl;
+ cout << wxT("FLOAT DATA TYPE: ") << typeInfFloat.TypeName << endl;
+ cout << wxT("DATE DATA TYPE: ") << typeInfDate.TypeName << endl;
+ cout << wxT("BLOB DATA TYPE: ") << typeInfBlob.TypeName << endl;
+ cout << endl;
+#endif
+
+ // Completed Successfully
+ return true;
+} // wxDb::Open() 2
+
+
+/********** wxDb::setConnectionOptions() **********/
+bool wxDb::setConnectionOptions(void)
+/*
+ * NOTE: The Intersolv/Oracle 7 driver was "Not Capable" of setting the login timeout.
+ */
+{
+ SWORD cb;
+
+ // I need to get the DBMS name here, because some of the connection options
+ // are database specific and need to call the Dbms() function.
+ if (SQLGetInfo(hdbc, SQL_DBMS_NAME, (UCHAR*) dbInf.dbmsName, 40, &cb) != SQL_SUCCESS)
+ return(DispAllErrors(henv, hdbc));
+
+ SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF);
+ SQLSetConnectOption(hdbc, SQL_OPT_TRACE, SQL_OPT_TRACE_OFF);
+// SQLSetConnectOption(hdbc, SQL_TXN_ISOLATION, SQL_TXN_READ_COMMITTED); // No dirty reads
+
+ // By default, MS Sql Server closes cursors on commit and rollback. The following
+ // call to SQLSetConnectOption() is needed to force SQL Server to preserve cursors
+ // after a transaction. This is a driver specific option and is not part of the
+ // ODBC standard. Note: this behavior is specific to the ODBC interface to SQL Server.
+ // The database settings don't have any effect one way or the other.
+ if (Dbms() == dbmsMS_SQL_SERVER)
+ {
+ const long SQL_PRESERVE_CURSORS = 1204L;
+ const long SQL_PC_ON = 1L;
+ SQLSetConnectOption(hdbc, SQL_PRESERVE_CURSORS, SQL_PC_ON);
+ }
+
+ // Display the connection options to verify them
+#ifdef DBDEBUG_CONSOLE
+ long l;
+ cout << wxT("****** CONNECTION OPTIONS ******") << endl;
+
+ if (SQLGetConnectOption(hdbc, SQL_AUTOCOMMIT, &l) != SQL_SUCCESS)
+ return(DispAllErrors(henv, hdbc));
+ cout << wxT("AUTOCOMMIT: ") << (l == SQL_AUTOCOMMIT_OFF ? "OFF" : "ON") << endl;
+
+ if (SQLGetConnectOption(hdbc, SQL_ODBC_CURSORS, &l) != SQL_SUCCESS)
+ return(DispAllErrors(henv, hdbc));
+ cout << wxT("ODBC CURSORS: ");
+ switch(l)
+ {
+ case(SQL_CUR_USE_IF_NEEDED):
+ cout << wxT("SQL_CUR_USE_IF_NEEDED");
+ break;
+ case(SQL_CUR_USE_ODBC):
+ cout << wxT("SQL_CUR_USE_ODBC");
+ break;
+ case(SQL_CUR_USE_DRIVER):
+ cout << wxT("SQL_CUR_USE_DRIVER");
+ break;
+ }
+ cout << endl;
+
+ if (SQLGetConnectOption(hdbc, SQL_OPT_TRACE, &l) != SQL_SUCCESS)
+ return(DispAllErrors(henv, hdbc));
+ cout << wxT("TRACING: ") << (l == SQL_OPT_TRACE_OFF ? wxT("OFF") : wxT("ON")) << endl;
+
+ cout << endl;
+#endif
+
+ // Completed Successfully
+ return true;
+
+} // wxDb::setConnectionOptions()
+
+
+/********** wxDb::getDbInfo() **********/
+bool wxDb::getDbInfo(bool failOnDataTypeUnsupported)
+{
+ SWORD cb;
+ RETCODE retcode;
+
+ retcode = SQLGetInfo(hdbc, SQL_SERVER_NAME, (UCHAR*) dbInf.serverName, 80, &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_DATABASE_NAME, (UCHAR*) dbInf.databaseName, 128, &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_DBMS_NAME, (UCHAR*) dbInf.dbmsName, 40, &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ // 16-Mar-1999
+ // After upgrading to MSVC6, the original 20 char buffer below was insufficient,
+ // causing database connectivity to fail in some cases.
+ retcode = SQLGetInfo(hdbc, SQL_DBMS_VER, (UCHAR*) dbInf.dbmsVer, 64, &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_ACTIVE_CONNECTIONS, (UCHAR*) &dbInf.maxConnections, sizeof(dbInf.maxConnections), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_ACTIVE_STATEMENTS, (UCHAR*) &dbInf.maxStmts, sizeof(dbInf.maxStmts), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_DRIVER_NAME, (UCHAR*) dbInf.driverName, 40, &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_DRIVER_ODBC_VER, (UCHAR*) dbInf.odbcVer, 60, &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_ODBC_VER, (UCHAR*) dbInf.drvMgrOdbcVer, 60, &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_DRIVER_VER, (UCHAR*) dbInf.driverVer, 60, &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_ODBC_API_CONFORMANCE, (UCHAR*) &dbInf.apiConfLvl, sizeof(dbInf.apiConfLvl), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_ODBC_SAG_CLI_CONFORMANCE, (UCHAR*) &dbInf.cliConfLvl, sizeof(dbInf.cliConfLvl), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ // Not all drivers support this call - Nick Gorham(unixODBC)
+ dbInf.cliConfLvl = 0;
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_ODBC_SQL_CONFORMANCE, (UCHAR*) &dbInf.sqlConfLvl, sizeof(dbInf.sqlConfLvl), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_OUTER_JOINS, (UCHAR*) dbInf.outerJoins, 2, &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_PROCEDURES, (UCHAR*) dbInf.procedureSupport, 2, &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_ACCESSIBLE_TABLES, (UCHAR*) dbInf.accessibleTables, 2, &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_CURSOR_COMMIT_BEHAVIOR, (UCHAR*) &dbInf.cursorCommitBehavior, sizeof(dbInf.cursorCommitBehavior), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_CURSOR_ROLLBACK_BEHAVIOR, (UCHAR*) &dbInf.cursorRollbackBehavior, sizeof(dbInf.cursorRollbackBehavior), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_NON_NULLABLE_COLUMNS, (UCHAR*) &dbInf.supportNotNullClause, sizeof(dbInf.supportNotNullClause), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_ODBC_SQL_OPT_IEF, (UCHAR*) dbInf.supportIEF, 2, &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_DEFAULT_TXN_ISOLATION, (UCHAR*) &dbInf.txnIsolation, sizeof(dbInf.txnIsolation), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_TXN_ISOLATION_OPTION, (UCHAR*) &dbInf.txnIsolationOptions, sizeof(dbInf.txnIsolationOptions), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_FETCH_DIRECTION, (UCHAR*) &dbInf.fetchDirections, sizeof(dbInf.fetchDirections), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_LOCK_TYPES, (UCHAR*) &dbInf.lockTypes, sizeof(dbInf.lockTypes), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_POS_OPERATIONS, (UCHAR*) &dbInf.posOperations, sizeof(dbInf.posOperations), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_POSITIONED_STATEMENTS, (UCHAR*) &dbInf.posStmts, sizeof(dbInf.posStmts), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_SCROLL_CONCURRENCY, (UCHAR*) &dbInf.scrollConcurrency, sizeof(dbInf.scrollConcurrency), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_SCROLL_OPTIONS, (UCHAR*) &dbInf.scrollOptions, sizeof(dbInf.scrollOptions), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_STATIC_SENSITIVITY, (UCHAR*) &dbInf.staticSensitivity, sizeof(dbInf.staticSensitivity), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_TXN_CAPABLE, (UCHAR*) &dbInf.txnCapable, sizeof(dbInf.txnCapable), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+ retcode = SQLGetInfo(hdbc, SQL_LOGIN_TIMEOUT, (UCHAR*) &dbInf.loginTimeout, sizeof(dbInf.loginTimeout), &cb);
+ if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
+ {
+ DispAllErrors(henv, hdbc);
+ if (failOnDataTypeUnsupported)
+ return false;
+ }
+
+#ifdef DBDEBUG_CONSOLE
+ cout << wxT("***** DATA SOURCE INFORMATION *****") << endl;
+ cout << wxT(wxT("SERVER Name: ") << dbInf.serverName << endl;
+ cout << wxT("DBMS Name: ") << dbInf.dbmsName << wxT("; DBMS Version: ") << dbInf.dbmsVer << endl;
+ cout << wxT("ODBC Version: ") << dbInf.odbcVer << wxT("; Driver Version: ") << dbInf.driverVer << endl;
+
+ cout << wxT("API Conf. Level: ");
+ switch(dbInf.apiConfLvl)
+ {
+ case SQL_OAC_NONE: cout << wxT("None"); break;
+ case SQL_OAC_LEVEL1: cout << wxT("Level 1"); break;
+ case SQL_OAC_LEVEL2: cout << wxT("Level 2"); break;
+ }
+ cout << endl;
+
+ cout << wxT("SAG CLI Conf. Level: ");
+ switch(dbInf.cliConfLvl)
+ {
+ case SQL_OSCC_NOT_COMPLIANT: cout << wxT("Not Compliant"); break;
+ case SQL_OSCC_COMPLIANT: cout << wxT("Compliant"); break;
+ }
+ cout << endl;
+
+ cout << wxT("SQL Conf. Level: ");
+ switch(dbInf.sqlConfLvl)
+ {
+ case SQL_OSC_MINIMUM: cout << wxT("Minimum Grammar"); break;
+ case SQL_OSC_CORE: cout << wxT("Core Grammar"); break;
+ case SQL_OSC_EXTENDED: cout << wxT("Extended Grammar"); break;
+ }
+ cout << endl;
+
+ cout << wxT("Max. Connections: ") << dbInf.maxConnections << endl;
+ cout << wxT("Outer Joins: ") << dbInf.outerJoins << endl;
+ cout << wxT("Support for Procedures: ") << dbInf.procedureSupport << endl;
+ cout << wxT("All tables accessible : ") << dbInf.accessibleTables << endl;
+ cout << wxT("Cursor COMMIT Behavior: ");
+ switch(dbInf.cursorCommitBehavior)
+ {
+ case SQL_CB_DELETE: cout << wxT("Delete cursors"); break;
+ case SQL_CB_CLOSE: cout << wxT("Close cursors"); break;
+ case SQL_CB_PRESERVE: cout << wxT("Preserve cursors"); break;
+ }
+ cout << endl;
+
+ cout << wxT("Cursor ROLLBACK Behavior: ");
+ switch(dbInf.cursorRollbackBehavior)
+ {
+ case SQL_CB_DELETE: cout << wxT("Delete cursors"); break;
+ case SQL_CB_CLOSE: cout << wxT("Close cursors"); break;
+ case SQL_CB_PRESERVE: cout << wxT("Preserve cursors"); break;
+ }
+ cout << endl;
+
+ cout << wxT("Support NOT NULL clause: ");
+ switch(dbInf.supportNotNullClause)
+ {
+ case SQL_NNC_NULL: cout << wxT("No"); break;
+ case SQL_NNC_NON_NULL: cout << wxT("Yes"); break;
+ }
+ cout << endl;
+
+ cout << wxT("Support IEF (Ref. Integrity): ") << dbInf.supportIEF << endl;
+ cout << wxT("Login Timeout: ") << dbInf.loginTimeout << endl;
+
+ cout << endl << endl << wxT("more ...") << endl;
+ getchar();
+
+ cout << wxT("Default Transaction Isolation: ";
+ switch(dbInf.txnIsolation)
+ {
+ case SQL_TXN_READ_UNCOMMITTED: cout << wxT("Read Uncommitted"); break;
+ case SQL_TXN_READ_COMMITTED: cout << wxT("Read Committed"); break;
+ case SQL_TXN_REPEATABLE_READ: cout << wxT("Repeatable Read"); break;
+ case SQL_TXN_SERIALIZABLE: cout << wxT("Serializable"); break;