home *** CD-ROM | disk | FTP | other *** search
- // bulkset.cpp : implementation file
- //
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
-
- #include "stdafx.h"
- #include "dbfetch.h"
- #include "bulkset.h"
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // CBulkRecordsetMod
-
- IMPLEMENT_DYNAMIC(CBulkRecordsetMod, CRecordset)
-
- CBulkRecordsetMod::CBulkRecordsetMod(CDatabase* pdb)
- : CRecordset(pdb)
- {
- //{{AFX_FIELD_INIT(CBulkRecordsetMod)
- //}}AFX_FIELD_INIT
- m_nDefaultType = dynaset;
- }
-
-
- BOOL CBulkRecordsetMod::Open(UINT nOpenType,
- LPCTSTR lpszSQL, DWORD dwOptions)
- {
- ASSERT(dwOptions & useMultiRowFetch);
- return CRecordset::Open(nOpenType, lpszSQL, dwOptions);
- }
-
- BOOL CBulkRecordsetMod::RowsetUpdate(WORD wRow, WORD wLockType)
- {
- ASSERT(wRow >= 0 && wRow <= GetRowsetSize());
-
- RETCODE nRetCode;
- AFX_ODBC_CALL(::SQLSetPos(m_hstmt, wRow, SQL_UPDATE, wLockType));
-
- return ValidateMod(wRow, SQL_ROW_UPDATED);
- }
-
- BOOL CBulkRecordsetMod::RowsetAdd(WORD wRow, WORD wLockType)
- {
- // User may allocate an extra row buffer for the Add
- // (if user adds more than 1, must override)
- ASSERT(wRow >= 0 && wRow <= GetRowsetSize() + 1);
-
- RETCODE nRetCode;
- AFX_ODBC_CALL(::SQLSetPos(m_hstmt, wRow, SQL_ADD, wLockType));
-
- return ValidateMod(wRow, SQL_ROW_ADDED);
- }
-
- BOOL CBulkRecordsetMod::RowsetDelete(WORD wRow, WORD wLockType)
- {
- ASSERT(wRow >= 0 && wRow <= GetRowsetSize());
-
- RETCODE nRetCode;
- AFX_ODBC_CALL(::SQLSetPos(m_hstmt, wRow, SQL_DELETE, wLockType));
-
- return ValidateMod(wRow, SQL_ROW_DELETED);
- }
-
- BOOL CBulkRecordsetMod::ValidateMod(WORD wRow, WORD wExpectedStatus)
- {
- BOOL bReturn = TRUE;
-
- if (wRow != 0)
- bReturn = GetRowStatus(wRow) == wExpectedStatus;
- else
- {
- for (WORD wNum = 1; wNum <= GetRowsetSize(); wNum++)
- {
- // If any row status not expected, then validate fails
- if (GetRowStatus(wNum) != wExpectedStatus)
- bReturn = FALSE;
- }
- }
-
- return bReturn;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CDynamicBulkSet
-
- IMPLEMENT_DYNAMIC(CDynamicBulkSet, CBulkRecordsetMod)
-
- CDynamicBulkSet::CDynamicBulkSet(CDatabase* pdb)
- : CBulkRecordsetMod(pdb)
- {
- m_nDefaultType = dynaset;
- m_nAllocatedFields = 0;
-
- m_ppvData = NULL;
- m_ppvLengths = NULL;
- }
-
- void CDynamicBulkSet::Close()
- {
- CRecordset::Close();
-
- delete [] m_ppvData;
- delete [] m_ppvLengths;
- }
-
- void CDynamicBulkSet::DoBulkFieldExchange(CFieldExchange* pFX)
- {
- // Allocate the buffer
- if (pFX->m_nOperation == CFieldExchange::AllocMultiRowBuffer &&
- m_nAllocatedFields == 0)
- {
- // get the field count
- m_ppvData = new void*[GetODBCFieldCount()];
- memset(m_ppvData, 0, sizeof(void*) * GetODBCFieldCount());
- m_ppvLengths = new void*[GetODBCFieldCount()];
- memset(m_ppvLengths, 0, sizeof(void*) * GetODBCFieldCount());
-
- m_nAllocatedFields = GetODBCFieldCount();
- m_nFields = m_nAllocatedFields;
- }
-
- // Should never get to here without field buffer allocation
- ASSERT(m_nAllocatedFields != 0);
-
- pFX->SetFieldType(CFieldExchange::outputColumn);
- for (int nNum = 0; nNum < GetODBCFieldCount(); nNum++)
- {
- RFX_Text_Bulk(pFX, _T("Dummy"), (LPSTR*)&m_ppvData[nNum],
- (long**)&m_ppvLengths[nNum], MAX_TEXT_LEN);
- }
- }
-
- void CDynamicBulkSet::CheckRowsetError(RETCODE nRetCode)
- {
- // Always IGNORE data truncated warnings, as the code
- // purposely truncates text to 40 chars...
-
- if (nRetCode == SQL_SUCCESS_WITH_INFO)
- {
- CDBException e(nRetCode);
- // Build the error string but don't send nuisance output to TRACE window
- e.BuildErrorString(m_pDatabase, m_hstmt, FALSE);
-
- if (e.m_strStateNativeOrigin.Find(_T("State:01004")) >= 0)
- {
- // Do nothing here for this app
- }
- else if (e.m_strStateNativeOrigin.Find(_T("State:01S01")) >= 0)
- {
- e.Empty();
- TRACE0("Error: fetching row from server.\n");
- ThrowDBException(AFX_SQL_ERROR_ROW_FETCH);
- }
- else
- {
- #ifdef _DEBUG
- // Not a truncation or row fetch warning so send debug output
- if (afxTraceFlags & traceDatabase)
- {
- TRACE0("Warning: ODBC Success With Info, ");
- e.TraceErrorMessage(e.m_strError);
- e.TraceErrorMessage(e.m_strStateNativeOrigin);
- }
- #endif // _DEBUG
- }
- }
- else if (!Check(nRetCode))
- ThrowDBException(nRetCode);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CTables - borrowed from Catalog2
-
- CTables::CTables(CDatabase* pDatabase)
- : CRecordset(pDatabase)
- {
- m_strTableQualifier = _T("");
- m_strTableOwner = _T("");
- m_strTableName = _T("");
- m_strTableType = _T("");
- m_strRemarks = _T("");
- m_nFields = 5;
- }
-
- BOOL CTables::Open(LPCSTR pszTableQualifier,
- LPCSTR pszTableOwner,LPCSTR pszTableName,LPCSTR pszTableType,
- UINT nOpenType)
- {
- ASSERT(m_pDatabase != NULL);
- ASSERT(m_pDatabase->IsOpen());
-
- RETCODE nRetCode;
- UWORD bFunctionExists;
-
- // make sure SQLTables exists
- AFX_SQL_SYNC(::SQLGetFunctions(m_pDatabase->m_hdbc,
- SQL_API_SQLTABLES,&bFunctionExists));
- if (!Check(nRetCode) || !bFunctionExists)
- {
- if (!bFunctionExists)
- TRACE(_T("SQLTables not supported\n"));
- return FALSE;
- }
-
- m_nOpenType = nOpenType;
- m_bUpdatable = FALSE;
-
- // make sure hstmt is allocated
- if (m_hstmt == SQL_NULL_HSTMT)
- {
- AFX_SQL_SYNC(::SQLAllocStmt(m_pDatabase->m_hdbc,&m_hstmt));
- if (!Check(nRetCode))
- ThrowDBException(nRetCode,m_hstmt);
- }
-
- OnSetOptions(m_hstmt);
-
- TRY
- {
- // call the ODBC function
- AFX_SQL_ASYNC(this,::SQLTables(m_hstmt,
- (UCHAR FAR*)pszTableQualifier,SQL_NTS,
- (UCHAR FAR*)pszTableOwner,SQL_NTS,
- (UCHAR FAR*)pszTableName,SQL_NTS,
- (UCHAR FAR*)pszTableType,SQL_NTS));
-
- if (!Check(nRetCode))
- ThrowDBException(nRetCode,m_hstmt);
-
- // Allocate memory and cache info
- AllocAndCacheFieldInfo();
- AllocRowset();
-
- // Allocate the field info and status arrays if
- // not done already in BuildSelectSQL
- if ((m_nFields != 0 || m_nParams != 0) &&
- m_rgFieldInfos == NULL)
- {
- AllocStatusArrays();
- }
-
- MoveNext();
- }
-
- CATCH_ALL(e)
- {
- Close();
- THROW_LAST();
- }
- END_CATCH_ALL
-
- return TRUE;
- }
-
- void CTables::DoFieldExchange(CFieldExchange* pFX)
- {
- pFX->SetFieldType(CFieldExchange::outputColumn);
- RFX_Text(pFX,_T("TABLE_QUALIFIER"),m_strTableQualifier);
- RFX_Text(pFX,_T("TABLE_OWNER"),m_strTableOwner);
- RFX_Text(pFX,_T("TABLE_NAME"),m_strTableName);
- RFX_Text(pFX,_T("TABLE_TYPE"),m_strTableType);
- RFX_Text(pFX,_T("REMARKS"),m_strRemarks);
- }
-