#include "ODBCRead.h" // Constructor ODBCRead::ODBCRead(CString strFile, CString strTable, CString strColumn, CString strCondition) { // Initial values fail = false; n = m = -1; data = NULL; m_strTable = _T(strTable); m_strColumn = _T(strColumn); bool where = false; if (strCondition != "") { m_strCondition = _T(strCondition); where = true; } else { m_strCondition.Empty(); } // SQL count records statement m_strCountRecords.Format(_T("SELECT COUNT(*) FROM [%s]"), m_strTable); // SQL data statement m_strSQL.Format(_T("SELECT %s FROM [%s]"), m_strColumn, strTable); // Add conditions on the rows returned if (where) { m_strCountRecords += _T(" WHERE ") + m_strCondition; m_strSQL += _T(" WHERE ") + m_strCondition; } // Error codes NUM_ERRS = 2; ERR_DATA_TYPE = 0; ERR_NUM_RECORDS = 1; // Indexes in the ErrorMessage string array // Error messages m_ErrorMessage = new CString [NUM_ERRS]; m_ErrorMessage[ERR_DATA_TYPE] = _T("The data base contains an unsupported data type"); m_ErrorMessage[ERR_NUM_RECORDS] = _T("An error occurred reading the number of records"); } // Destructor ODBCRead::~ODBCRead(void) { if (data) { delete [] data; data = NULL; } delete [] m_ErrorMessage; m_database.Close(); } // Get the number of records long ODBCRead::countRecords(void) { CRecordset countRecordset(&m_database); countRecordset.Open(CRecordset::forwardOnly,m_strCountRecords,CRecordset::executeDirect); CString strValue; if (!countRecordset.IsEOF()) countRecordset.GetFieldValue((short)0,strValue); countRecordset.Close(); return (atol(strValue)); } void ODBCRead::read(void) { // Connect to the database try { // Open the database if (m_strConnect.IsEmpty()) { m_database.Open(NULL); // User can select a DSN connection from dialog box } else { m_database.Open(NULL,false,false,m_strConnect,false); // Use file information } if (m_database.IsOpen()) { // Attach a recordset CRecordset recordset(&m_database); // Execute the SQL query recordset.Open(CRecordset::forwardOnly,m_strSQL,CRecordset::readOnly); // Set public data members n = countRecords(); m = recordset.GetODBCFieldCount(); data = new double [n * m]; CDBVariant datavalue; long i = 0, k = 0; while (!recordset.IsEOF()) { for (short j = 0; j < (short)m; j++) { recordset.GetFieldValue(j,datavalue); switch(datavalue.m_dwType) { case(DBVT_BOOL): data[k + j] = (double)datavalue.m_boolVal; break; case(DBVT_SHORT): data[k + j] = (double)datavalue.m_iVal; break; case(DBVT_LONG): data[k + j] = (double)datavalue.m_lVal; break; case(DBVT_SINGLE): data[k + j] = (double)datavalue.m_fltVal; break; case(DBVT_DOUBLE): data[k + j] = (double)datavalue.m_dblVal; break; default: // No support for non-numeric types throw ERR_DATA_TYPE; break; } } recordset.MoveNext(); i++; k += m; } // Close the recordset recordset.Close(); // Check that all records have been processed if (i != n) { throw ERR_NUM_RECORDS; } } } catch (CDBException* e) { AfxMessageBox(e->m_strError); // Present user with ODBC Error in a message box e->Delete(); // Return memory ODBCRead::~ODBCRead(); fail = true; // Set fail flag } catch (unsigned int e) { AfxMessageBox(m_ErrorMessage[e]); ODBCRead::~ODBCRead(); fail = true; } } void ODBCRead::info(bool always) { if (always || fail) { CString strInfo = (m_strConnect.IsEmpty() ? _T("DSN Connection") : _T("Connection string:\n")+ m_strConnect); strInfo += _T("\n\nCount records statement:\n") + m_strCountRecords + _T("\n\nSQL statement:\n") + m_strSQL; AfxMessageBox(strInfo); } }