|
|
|
@ -1209,20 +1209,19 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols) |
|
|
|
RETCODE rc; |
|
|
|
HSTMT hstmt; |
|
|
|
|
|
|
|
//m_Recset = new(m_G) RECSET(this);
|
|
|
|
//ASSERT(m_Recset);
|
|
|
|
|
|
|
|
try { |
|
|
|
b = false; |
|
|
|
|
|
|
|
if (m_hstmt) { |
|
|
|
/*RETCODE rc;*/ |
|
|
|
|
|
|
|
// All this did not seems to make sense and was been commented out
|
|
|
|
// if (IsOpen())
|
|
|
|
// Close(SQL_CLOSE);
|
|
|
|
|
|
|
|
/*rc =*/ SQLFreeStmt(m_hstmt, SQL_CLOSE); |
|
|
|
rc = SQLFreeStmt(m_hstmt, SQL_CLOSE); |
|
|
|
|
|
|
|
if (trace && !Check(rc)) |
|
|
|
htrc("Error: SQLFreeStmt rc=%d\n", rc); |
|
|
|
|
|
|
|
hstmt = m_hstmt; |
|
|
|
m_hstmt = NULL; |
|
|
|
ThrowDBX(MSG(SEQUENCE_ERROR)); |
|
|
|
@ -1339,7 +1338,6 @@ int ODBConn::GetResultSize(char *sql, ODBCCOL *colp) |
|
|
|
} // endfor n
|
|
|
|
|
|
|
|
} catch(DBX *x) { |
|
|
|
// strcpy(m_G->Message, x->m_ErrMsg[0]);
|
|
|
|
strcpy(m_G->Message, x->GetErrorMessage(0)); |
|
|
|
|
|
|
|
if (trace) |
|
|
|
@ -1515,7 +1513,6 @@ bool ODBConn::BindParam(ODBCCOL *colp) |
|
|
|
#endif // 0
|
|
|
|
|
|
|
|
buf = colp->GetBuffer(0); |
|
|
|
// len = colp->GetBuflen();
|
|
|
|
len = IsTypeNum(colp->GetResultType()) ? 0 : colp->GetBuflen(); |
|
|
|
ct = GetSQLCType(colp->GetResultType()); |
|
|
|
sqlt = GetSQLType(colp->GetResultType()); |
|
|
|
@ -1579,7 +1576,6 @@ bool ODBConn::GetDataSources(PQRYRES qrp) |
|
|
|
rv = true; |
|
|
|
} // end try/catch
|
|
|
|
|
|
|
|
//SQLFreeEnv(m_henv);
|
|
|
|
Close(); |
|
|
|
return rv; |
|
|
|
} // end of GetDataSources
|
|
|
|
@ -1631,7 +1627,6 @@ bool ODBConn::GetDrivers(PQRYRES qrp) |
|
|
|
rv = true; |
|
|
|
} // end try/catch
|
|
|
|
|
|
|
|
//SQLFreeEnv(m_henv);
|
|
|
|
Close(); |
|
|
|
return rv; |
|
|
|
} // end of GetDrivers
|
|
|
|
@ -1800,7 +1795,6 @@ int ODBConn::GetCatInfo(CATPARM *cap) |
|
|
|
} else // ODBC Ver 3
|
|
|
|
rc = SQLFetch(hstmt); |
|
|
|
|
|
|
|
// if (!Check(rc))
|
|
|
|
if (rc == SQL_NO_DATA_FOUND) { |
|
|
|
if (cap->Pat) |
|
|
|
sprintf(m_G->Message, MSG(NO_TABCOL_DATA), cap->Tab, cap->Pat); |
|
|
|
@ -1836,270 +1830,35 @@ int ODBConn::GetCatInfo(CATPARM *cap) |
|
|
|
/***********************************************************************/ |
|
|
|
void ODBConn::Close() |
|
|
|
{ |
|
|
|
/*RETCODE rc;*/ |
|
|
|
|
|
|
|
#if 0
|
|
|
|
// Close any open recordsets
|
|
|
|
AfxLockGlobals(CRIT_ODBC); |
|
|
|
TRY |
|
|
|
{ |
|
|
|
while (!m_listRecordsets.IsEmpty()) |
|
|
|
{ |
|
|
|
CRecordset* pSet = (CRecordset*)m_listRecordsets.GetHead(); |
|
|
|
pSet->Close(); // will implicitly remove from list
|
|
|
|
pSet->m_pDatabase = NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
CATCH_ALL(e) |
|
|
|
{ |
|
|
|
AfxUnlockGlobals(CRIT_ODBC); |
|
|
|
THROW_LAST(); |
|
|
|
} |
|
|
|
END_CATCH_ALL |
|
|
|
AfxUnlockGlobals(CRIT_ODBC); |
|
|
|
#endif // 0
|
|
|
|
RETCODE rc; |
|
|
|
|
|
|
|
if (m_hstmt) { |
|
|
|
// Is required for multiple tables
|
|
|
|
/*rc =*/ SQLFreeStmt(m_hstmt, SQL_DROP); |
|
|
|
rc = SQLFreeStmt(m_hstmt, SQL_DROP); |
|
|
|
m_hstmt = NULL; |
|
|
|
} // endif m_hstmt
|
|
|
|
|
|
|
|
if (m_hdbc != SQL_NULL_HDBC) { |
|
|
|
/*rc =*/ SQLDisconnect(m_hdbc); |
|
|
|
/*rc =*/ SQLFreeConnect(m_hdbc); |
|
|
|
m_hdbc = SQL_NULL_HDBC; |
|
|
|
rc = SQLDisconnect(m_hdbc); |
|
|
|
|
|
|
|
// AfxLockGlobals(CRIT_ODBC);
|
|
|
|
// ASSERT(m_nAlloc != 0);
|
|
|
|
// m_nAlloc--;
|
|
|
|
// AfxUnlockGlobals(CRIT_ODBC);
|
|
|
|
} // endif m_hdbc
|
|
|
|
if (trace && rc != SQL_SUCCESS) |
|
|
|
htrc("Error: SQLDisconnect rc=%d\n", rc); |
|
|
|
|
|
|
|
if (m_henv != SQL_NULL_HENV) { |
|
|
|
if (trace) { |
|
|
|
RETCODE rc = SQLFreeEnv(m_henv); |
|
|
|
|
|
|
|
if (rc != SQL_SUCCESS) // Nothing we can do
|
|
|
|
htrc("Error: SQLFreeEnv failure ignored in Close\n"); |
|
|
|
|
|
|
|
} else |
|
|
|
SQLFreeEnv(m_henv); |
|
|
|
rc = SQLFreeConnect(m_hdbc); |
|
|
|
|
|
|
|
m_henv = SQL_NULL_HENV; |
|
|
|
} // endif m_henv
|
|
|
|
if (trace && rc != SQL_SUCCESS) |
|
|
|
htrc("Error: SQLFreeConnect rc=%d\n", rc); |
|
|
|
|
|
|
|
} // end of Close
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
// Silently disconnect and free all ODBC resources.
|
|
|
|
// Don't throw any exceptions
|
|
|
|
void ODBConn::Free() |
|
|
|
{ |
|
|
|
// Trap failures upon close
|
|
|
|
try { |
|
|
|
Close(); |
|
|
|
} catch(DBX*) { |
|
|
|
// Nothing we can do
|
|
|
|
if (trace) |
|
|
|
htrc("Error: exception by Close ignored in Free\n"); |
|
|
|
|
|
|
|
// DELETE_EXCEPTION(x);
|
|
|
|
} // endcatch
|
|
|
|
m_hdbc = SQL_NULL_HDBC; |
|
|
|
} // endif m_hdbc
|
|
|
|
|
|
|
|
// free henv if refcount goes to 0
|
|
|
|
//AfxLockGlobals(CRIT_ODBC);
|
|
|
|
if (m_henv != SQL_NULL_HENV) { |
|
|
|
ASSERT(m_nAlloc >= 0); |
|
|
|
|
|
|
|
if (m_nAlloc == 0) { |
|
|
|
// free last connection - release HENV
|
|
|
|
if (trace) { |
|
|
|
RETCODE rc = SQLFreeEnv(m_henv); |
|
|
|
|
|
|
|
if (rc != SQL_SUCCESS) // Nothing we can do
|
|
|
|
htrc("Error: SQLFreeEnv failure ignored in Free\n"); |
|
|
|
|
|
|
|
} else |
|
|
|
SQLFreeEnv(m_henv); |
|
|
|
rc = SQLFreeEnv(m_henv); |
|
|
|
|
|
|
|
m_henv = SQL_NULL_HENV; |
|
|
|
} // endif m_nAlloc
|
|
|
|
if (trace && rc != SQL_SUCCESS) // Nothing we can do
|
|
|
|
htrc("Error: SQLFreeEnv failure ignored in Close\n"); |
|
|
|
|
|
|
|
m_henv = SQL_NULL_HENV; |
|
|
|
} // endif m_henv
|
|
|
|
//AfxUnlockGlobals(CRIT_ODBC);
|
|
|
|
} // end of Free
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// CRecordset helpers
|
|
|
|
|
|
|
|
//id AFXAPI AfxSetCurrentRecord(int* plCurrentRecord, int nRows, RETCODE nRetCode);
|
|
|
|
//id AFXAPI AfxSetRecordCount(int* plRecordCount, int lCurrentRecord,
|
|
|
|
//bool bEOFSeen, RETCODE nRetCode);
|
|
|
|
|
|
|
|
/***********************************************************************/ |
|
|
|
/* RECSET class implementation */ |
|
|
|
/***********************************************************************/ |
|
|
|
RECSET::RECSET(ODBConn *dbcp) |
|
|
|
{ |
|
|
|
m_pDB = dbcp; |
|
|
|
m_hstmt = SQL_NULL_HSTMT; |
|
|
|
m_OpenType = snapshot; |
|
|
|
m_Options = none; |
|
|
|
|
|
|
|
#if 0
|
|
|
|
m_lOpen = AFX_RECORDSET_STATUS_UNKNOWN; |
|
|
|
m_nEditMode = noMode; |
|
|
|
m_nDefaultType = snapshot; |
|
|
|
|
|
|
|
m_bAppendable = false; |
|
|
|
m_bUpdatable = false; |
|
|
|
m_bScrollable = false; |
|
|
|
m_bRecordsetDb = false; |
|
|
|
m_bRebindParams = false; |
|
|
|
m_bLongBinaryColumns = false; |
|
|
|
m_nLockMode = optimistic; |
|
|
|
m_dwInitialGetDataLen = 0; |
|
|
|
m_rgODBCFieldInfos = NULL; |
|
|
|
m_rgFieldInfos = NULL; |
|
|
|
m_rgRowStatus = NULL; |
|
|
|
m_dwRowsetSize = 25; |
|
|
|
m_dwAllocatedRowsetSize = 0; |
|
|
|
|
|
|
|
m_nFields = 0; |
|
|
|
m_nParams = 0; |
|
|
|
m_nFieldsBound = 0; |
|
|
|
m_lCurrentRecord = AFX_CURRENT_RECORD_UNDEFINED; |
|
|
|
m_lRecordCount = 0; |
|
|
|
m_bUseUpdateSQL = false; |
|
|
|
m_bUseODBCCursorLib = false; |
|
|
|
m_nResultCols = -1; |
|
|
|
m_bCheckCacheForDirtyFields = true; |
|
|
|
|
|
|
|
m_pbFieldFlags = NULL; |
|
|
|
m_pbParamFlags = NULL; |
|
|
|
m_plParamLength = NULL; |
|
|
|
m_pvFieldProxy = NULL; |
|
|
|
m_pvParamProxy = NULL; |
|
|
|
m_nProxyFields = 0; |
|
|
|
m_nProxyParams = 0; |
|
|
|
|
|
|
|
m_hstmtUpdate = SQL_NULL_HSTMT; |
|
|
|
#endif // 0
|
|
|
|
} // end of RECSET constructor
|
|
|
|
|
|
|
|
RECSET::~RECSET() |
|
|
|
{ |
|
|
|
try { |
|
|
|
if (m_hstmt) { |
|
|
|
if (trace && (m_dwOptions & useMultiRowFetch)) { |
|
|
|
htrc("WARNING: Close called implicitly from destructor\n"); |
|
|
|
htrc("Use of multi row fetch requires explicit call\n"); |
|
|
|
htrc("to Close or memory leaks will result\n"); |
|
|
|
} // endif trace
|
|
|
|
|
|
|
|
Close(); |
|
|
|
} // endif m_hstmt
|
|
|
|
|
|
|
|
// if (m_bRecordsetDb)
|
|
|
|
// delete m_pDB; ??????
|
|
|
|
|
|
|
|
m_pDB = NULL; |
|
|
|
} catch(DBX*) { |
|
|
|
// Nothing we can do
|
|
|
|
if (trace) |
|
|
|
htrc("Error: Exception ignored in ~RECSET\n"); |
|
|
|
|
|
|
|
} // endtry/catch
|
|
|
|
|
|
|
|
} // end of ~RECSET
|
|
|
|
|
|
|
|
/***********************************************************************/ |
|
|
|
/* Open: this function does the following: */ |
|
|
|
/* Allocates the hstmt, */ |
|
|
|
/* Bind columns, */ |
|
|
|
/* Execute the SQL statement */ |
|
|
|
/***********************************************************************/ |
|
|
|
bool RECSET::Open(PSZ sql, uint Type, DWORD options) |
|
|
|
{ |
|
|
|
ASSERT(m_pDB && m_pDB->IsOpen()); |
|
|
|
ASSERT(Type == DB_USE_DEFAULT_TYPE || Type == dynaset || |
|
|
|
Type == snapshot || Type == forwardOnly || Type == dynamic); |
|
|
|
//ASSERT(!(options & readOnly && options & appendOnly));
|
|
|
|
|
|
|
|
// Cache state info and allocate hstmt
|
|
|
|
SetState(Type, sql, options); |
|
|
|
|
|
|
|
try { |
|
|
|
if (m_hstmt) { |
|
|
|
if (IsOpen()) |
|
|
|
Close(SQL_CLOSE); |
|
|
|
|
|
|
|
} else { |
|
|
|
RETCODE rc = SQLAllocStmt(m_pDB->m_hdbc, &m_hstmt); |
|
|
|
|
|
|
|
if (!Check(rc)) |
|
|
|
ThrowDBException(SQL_INVALID_HANDLE); |
|
|
|
|
|
|
|
} // endif m_hstmt
|
|
|
|
|
|
|
|
m_pDB->OnSetOptions(m_hstmt); |
|
|
|
|
|
|
|
// Allocate the field/param status arrays, if necessary
|
|
|
|
// bool bUnbound = false;
|
|
|
|
|
|
|
|
// if (m_nFields > 0 || m_nParams > 0)
|
|
|
|
// AllocStatusArrays();
|
|
|
|
// else
|
|
|
|
// bUnbound = true;
|
|
|
|
|
|
|
|
// Build SQL and prep/execute or just execute direct
|
|
|
|
// BuildSQL(sql);
|
|
|
|
PrepareAndExecute(sql); |
|
|
|
|
|
|
|
// Cache some field info and prepare the rowset
|
|
|
|
AllocAndCacheFieldInfo(); |
|
|
|
AllocRowset(); |
|
|
|
|
|
|
|
// If late binding, still need to allocate status arrays
|
|
|
|
// if (bUnbound && (m_nFields > 0 || m_nParams > 0))
|
|
|
|
// AllocStatusArrays();
|
|
|
|
|
|
|
|
} catch(DBX *x) { |
|
|
|
Close(SQL_DROP); |
|
|
|
// strcpy(m_pDB->m_G->Message, x->GetErrorMessage[0]);
|
|
|
|
strcpy(m_pDB->m_G->Message, x->GetErrorMessage(0)); |
|
|
|
return true; |
|
|
|
} // endtry/catch
|
|
|
|
|
|
|
|
return false; |
|
|
|
} // end of Open
|
|
|
|
|
|
|
|
/***********************************************************************/ |
|
|
|
/* Close a hstmt. */ |
|
|
|
/***********************************************************************/ |
|
|
|
void RECSET::Close(SWORD option) |
|
|
|
{ |
|
|
|
if (m_hstmt != SQL_NULL_HSTMT) { |
|
|
|
RETCODE rc = SQLFreeStmt(m_hstmt, option); |
|
|
|
|
|
|
|
if (option == SQL_DROP) |
|
|
|
m_hstmt = SQL_NULL_HSTMT; |
|
|
|
|
|
|
|
} // endif m_hstmt
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
m_lOpen = RECORDSET_STATUS_CLOSED; |
|
|
|
m_bBOF = true; |
|
|
|
m_bEOF = true; |
|
|
|
m_bDeleted = false; |
|
|
|
m_bAppendable = false; |
|
|
|
m_bUpdatable = false; |
|
|
|
m_bScrollable = false; |
|
|
|
m_bRebindParams = false; |
|
|
|
m_bLongBinaryColumns = false; |
|
|
|
m_nLockMode = optimistic; |
|
|
|
m_nFieldsBound = 0; |
|
|
|
m_nResultCols = -1; |
|
|
|
#endif // 0
|
|
|
|
} // end of Close
|
|
|
|
#endif // 0
|