⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 axrecordset.cpp

📁 一个非常好用的ADO封装类,程序员不再需要跟烦人的COM接口打交道,写数据库程序不再麻烦!
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	if FAILED( hr )
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Move"), hr);
		
  if ( !IsBOF() && !IsEOF() )
	  DoFieldExchange(FALSE);
}

// Method: MoveFirst
//   Desc: Sets the record pointer to the first record in the recordset.
//
//   Args: none 
//
// Return: void
//
void CAxRecordset::MoveFirst()
{
	VALID_ADO_OBJECT(m_piRecordset);

	if ( _IsEmpty() )
    return;

  HRESULT hr = m_piRecordset->MoveFirst();
	if FAILED( hr )
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::MoveFirst"), hr);

	DoFieldExchange(FALSE);
}

// Method: MoveLast
//   Desc: Sets the record pointer to the last record in the recordset.
//
//   Args: none 
//
// Return: void
//
void CAxRecordset::MoveLast()
{
	VALID_ADO_OBJECT(m_piRecordset);

	if ( _IsEmpty() )
    return;

	HRESULT hr = m_piRecordset->MoveLast();
	if FAILED( hr )
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::MoveLast"), hr);

	DoFieldExchange(FALSE);
}

// Method: MoveNext
//   Desc: Sets the record pointer to the next record in the recordset.
//         If the record pointer is on the last record before a call to
//         MoveNext, the record pointer is moved beyond the last record
//         and the EOF property is set to true.
//
//   Args: none 
//
// Return: void
//
void CAxRecordset::MoveNext()
{
	VALID_ADO_OBJECT(m_piRecordset);

//  if ( _IsEmpty() || IsEOF() )
//    if ( IsEOF() )
//    return;

  HRESULT hr = m_piRecordset->MoveNext();
	if FAILED( hr )
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::MoveNext"), hr);

	if ( !IsEOF() )
		DoFieldExchange(FALSE);
}

// Method: MovePrevious
//   Desc: Sets the record pointer to the previous record in the recordset.
//         If the record pointer is on the first record before a call to
//         MovePrevious, the record pointer is moved to a position before
//         the first record and the BOF property is set to true.
//
//   Args: none 
//
// Return: void
//
void CAxRecordset::MovePrevious()
{
	VALID_ADO_OBJECT(m_piRecordset);

//  if ( _IsEmpty() || IsBOF() )
//    return;

  HRESULT hr = m_piRecordset->MovePrevious();
  if FAILED( hr )
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::MovePrevious"), hr);

	if ( !IsBOF() )
		DoFieldExchange(FALSE);
}

// Method: NextRecordset
//   Desc: Not supported in this version of AxLib
//
void CAxRecordset::NextRecordset()
{
}

// Method: Open
//   Desc: The first version of the Open method accepts a CAxCommand object
//         whereby a stored procedure is used to return recordset results.
//         A derived CAxRecordset object must exist and be initialized before
//         calling the Open method. If the method fails, a CAxException is
//         thrown.
//
//   Args: 
//        pCmd: Reference to a CAxCommand object.
//       cType: Cursor type to use, default is adOpenForwardOnly
//      cLocat: Cursor location, default is adUseClient
//       lType: Lock type to use, default is adLockOptimistic
//    nOptions: Command options, default is adCmdUnspecified
//
// Return: void
//
void CAxRecordset::Open(CAxCommand* pCmd, 
				                CursorTypeEnum eCursorType,
				                CursorLocationEnum eCursorLocation,
				                LockTypeEnum eLockType,
				                long nOptions)
{
  if ( m_piRecordset == NULL )
  {
    HRESULT hr = Create();
    if  FAILED ( hr )
      ThrowAxException(AXLIB_ERROR_INIT, _T("CAxRecordset::Open"), hr);
  }

  VALID_ADO_OBJECT(m_piRecordset);
  VARIANT vNull, vCmd;
  HRESULT hr = S_OK;

	vNull.vt = VT_ERROR;
	vNull.scode = DISP_E_PARAMNOTFOUND;

	vCmd.vt = VT_DISPATCH;
	vCmd.pdispVal = pCmd->m_piCommand;

  //Capture references to controlling objects
  m_pConnection = pCmd->ActiveConnection();
  m_pCommand = pCmd;
  m_piConnection = m_pConnection->_GetActiveConnection();

  //Create command object's parameters (one time only) and Update
  //Note: v1.2.0 now calls the _CreateParameters method from within the
  //CAxCommand::Create method
  m_pCommand->_UpdateParameters();

  CursorTypeEnum ct = (m_eCursorType == -2) ? eCursorType : m_eCursorType;
  LockTypeEnum lt = (m_eLockType == -2) ? eLockType : m_eLockType;
  CursorLocation(eCursorLocation);

  hr = m_piRecordset->Open(vCmd, vNull, ct, lt, nOptions);
	if FAILED( hr )
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Open"), hr);

  hr = m_piRecordset->get_Fields(&m_pFields);
	if FAILED( hr )
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Open"), hr);

	DoFieldExchange(FALSE);
}

// Method: Open
//   Desc: The second version of the Open method uses a source argument in
//         place of a CAxCommand object. A typical source statement would 
//         be "SELECT * From Accounts ORDER By AccountID"
//
// v1.1.1: Added call to CursorLocation
//
//   Args: 
//        szSource: Valid SQL Source statement
//     pConnection: Reference to an existing CAxConnection object
//           cType: Cursor type to use, default is adOpenForwardOnly
//          cLocat: Cursor location, default is adUseClient
//           lType: Lock type to use, default is adLockOptimistic
//        nOptions: Command options, default is adCmdUnspecified
//
// Return: void
//
void CAxRecordset::Open(LPCTSTR szSource, CAxConnection *pConnection,
				                CursorTypeEnum eCursorType,
				                CursorLocationEnum eCursorLocation,
				                LockTypeEnum eLockType,
				                long nOptions)
{
  if ( m_piRecordset == NULL )
  {
    HRESULT hr = Create();
    if  FAILED ( hr )
      ThrowAxException(AXLIB_ERROR_INIT, _T("CAxRecordset::Open"), hr);
  }

  VALID_ADO_OBJECT(m_piRecordset);
  HRESULT hr = S_OK;

	if ( szSource != NULL )
    m_strSourceString = szSource;

	if ( pConnection != NULL )
		m_piConnection = pConnection->_GetActiveConnection();

	ASSERT( !m_strSourceString.IsEmpty() );
	ASSERT( m_piConnection != NULL );

  hr =  m_piRecordset->put_Source(m_strSourceString.AllocSysString());
	if FAILED( hr )
	{
		m_piRecordset->Release();
		m_piRecordset = NULL;
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Open"), hr);
	}

  hr = m_piRecordset->putref_ActiveConnection((ADOConnection*)m_piConnection);
	if FAILED( hr )
	{
		m_piRecordset->Release();
		m_piRecordset = NULL;
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Open"), hr);
	}

  CursorTypeEnum ct = (m_eCursorType == -2) ? eCursorType : m_eCursorType;
  LockTypeEnum lt = (m_eLockType == -2) ? eLockType : m_eLockType;
  CursorLocation(eCursorLocation);

  hr = m_piRecordset->Open(_variant_t(szSource), _variant_t(m_piConnection),
    ct, lt, nOptions);

	if FAILED( hr )
	{
		m_piRecordset->Release();
		m_piRecordset = NULL;
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Open"), hr);
	}

  hr = m_piRecordset->get_Fields(&m_pFields);
	if FAILED( hr )
	{
		m_piRecordset->Release();
		m_piRecordset = NULL;
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Open"), hr);
	}

  DoFieldExchange(FALSE);
}

// Method: Requery
//   Desc: The Requery method re-executes the command that was used to
//         originally open the recordset. If the recordset was opened
//         using a command object (i.e. CAxCommand), Requery is used to
//         update the recordset after changing one or more parameter
//         values of the command.
//
//   Args: 
//      eExecuteOption: Execute option, default is adOptionUnspecified
//        adOptionUnspecified	= -1,
//        adAsyncExecute	= 0x10,
//        adAsyncFetch	= 0x20,
//        adAsyncFetchNonBlocking	= 0x40,
//        adExecuteNoRecords	= 0x80
//
// Return: void
//
void CAxRecordset::Requery(ExecuteOptionEnum eExecuteOption)
{
	VALID_ADO_OBJECT(m_piRecordset);

  if ( m_pCommand )
    m_pCommand->_UpdateParameters();

  HRESULT hr = m_piRecordset->Requery(eExecuteOption);
	if FAILED( hr )
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Requery"), hr);
  
	DoFieldExchange(FALSE);
}

// Method: Resync
//   Desc: The Resync method is used to resychronize the the records
//         with the data provider. Resync is typically used when the
//         recordset was opened using a Static or Forward only cursor
//         and the client application needs to check is any other users
//         have made changes.
//
//   Args: 
//      eAffectRecords: Affect records options, default is adAffectAll
//        adAffectCurrent	= 1,
//        adAffectGroup	= 2,
//        adAffectAll	= 3,
//        adAffectAllChapters	= 4
//
//      eResyncValues: Resync option, default is adResyncAllValues
//        adResyncUnderlyingValues	= 1,
//        adResyncAllValues	= 2
//
// Return: void
//
void CAxRecordset::Resync(AffectEnum eAffectRecords,
                                ResyncEnum eResyncValues) 
{
	VALID_ADO_OBJECT(m_piRecordset);

  HRESULT hr = m_piRecordset->Resync(eAffectRecords, eResyncValues);
	if FAILED( hr )
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Resync"), hr);
}

// Method: Save
//   Desc: Saves the recordset to a file. The AxLib version differs
//         from ADO in that a file name is used as the destination
//         argument rather than a variant. Therefore, only saving
//         to a file is supported.
//
//   Args: 
//      lpszFileName: File name to save recordset data to.
//    ePersistFormat: Persist format option, default is adPersistADTG
//      adPersistADTG	= 0,
//      adPersistXML	= 1
//
// Return: void
//
void CAxRecordset::Save(LPCTSTR lpszFileName,
                              PersistFormatEnum ePersistFormat) 
{
#if _MSC_VER == 1200
  _bstr_t bstrFileName(lpszFileName);
  HRESULT hr = m_piRecordset->Save(bstrFileName, ePersistFormat);
#else
  #ifdef _UNICODE
    _variant_t varFile(lpszFileName);
  #else
    _variant_t varFile(M2W(lpszFileName));
  #endif
  HRESULT hr = m_piRecordset->Save(varFile, ePersistFormat);
#endif

  if FAILED( hr )
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Save"), hr);
}


// Method: Supports
//   Desc: Determines if the data provider supports a certain
//         functionality.
//
//   Args: 
//      eCursorOption: Cursor option to validate
//        adHoldRecords	= 0x100,
//        adMovePrevious	= 0x200,
//        adAddNew	= 0x1000400,
//        adDelete	= 0x1000800,
//        adUpdate	= 0x1008000,
//        adBookmark	= 0x2000,
//        adApproxPosition	= 0x4000,
//        adUpdateBatch	= 0x10000,
//        adResync	= 0x20000,
//        adNotify	= 0x40000,
//        adFind	= 0x80000
//
// Return: If the data provider supports the indicated option true,
//         otherwise false.
//
bool CAxRecordset::Supports(CursorOptionEnum eCursorOption)
{
	VALID_ADO_OBJECT(m_piRecordset);
	VARIANT_BOOL vSucceeded;
	
  HRESULT hr = m_piRecordset->Supports(eCursorOption, &vSucceeded);
	if FAILED( hr )
    ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Supports"), hr);

	return ( vSucceeded != 0 );
}

// Method: Update
//   Desc: Posts changes made to the recordset back to the server. The
//         Update method calls the virtual function DoFieldExchange in
//         the derived CAxRecordset object to write individual field
//         data back to the data provider.
//
//   Args: none
//
// Return: void
//
void CAxRecordset::Update()
{
	VALID_ADO_OBJECT(m_piRecordset);
	_variant_t vNames(DISP_E_PARAMNOTFOUND, VT_ERROR);
	_variant_t vValues(DISP_E_PARAMNOTFOUND, VT_ERROR);

	DoFieldExchange(TRUE);

	//Use 'adResyncUnderlyingValues' on Resync to avoid errors on compound
	//Recordsets (i.e. INNER/OUTER Joins of tables)
  HRESULT hr = S_OK;
	if ( Supports(adResync) )
	{
		if FAILED( m_piRecordset->Resync(adAffectCurrent, adResyncUnderlyingValues) )
		{
      hr = m_piRecordset->Resync(adAffectCurrent, adResyncAllValues);
			if FAILED( hr )
        ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Update"), hr);
		}
	}

	if ( Supports(adUpdate) )
	{
    hr = m_piRecordset->Update(vNames, vValues);
		if FAILED( hr )
      ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::Update"), hr);
	}
}


///////////////////////////////////////////////////////////////
//	Properties

// Method: AbsolutePage
//   Desc: Sets/Returns the current page in the record set.
//         Call method with no argument to return current setting.
//
//   Args: nPage
//          Page to set active. Page value must be between
//          1 and the total page count. Page count is 
//          returned by the PageCount() method.
//
// Return: Current page or PositionEnum value.
//            adPosUnknown	= -1,
//            adPosBOF	= -2,
//            adPosEOF	= -3
//
long CAxRecordset::AbsolutePage(long nPageNum)
{
	VALID_ADO_OBJECT(m_piRecordset);
  HRESULT hr = S_OK;

  if ( nPageNum < 0 || nPageNum > PageCount() )
		  ThrowAxException(AXLIB_ERROR_INVALID_POS, _T("CAxRecordset::AbsolutePage"));

  if ( nPageNum > 0 )
  {
    hr = m_piRecordset->put_AbsolutePage((PositionEnum)nPageNum);
	  if FAILED( hr )
		  ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::AbsolutePage"), hr);
  }

	PositionEnum pageNum;
  hr = m_piRecordset->get_AbsolutePage(&pageNum);
	if FAILED( hr )
		ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::AbsolutePage"), hr);

	return ((PositionEnum)pageNum);
}

// Method: AbsolutePage
//   Desc: Sets/Returns the current record position.
//         Call method with no argument to return current setting.
//
//   Args: nPosition
//          Position to set the current record. Position is 1' based.
//          Position is between 1 and the record count. Record count
//          is returned by the RecordCount() method.
//
// Return: Current record position (ordinal value) or PositionEnum value.
//            adPosUnknown	= -1,
//            adPosBOF	= -2,
//            adPosEOF	= -3
//
long CAxRecordset::AbsolutePosition(long nPosition)
{
	VALID_ADO_OBJECT(m_piRecordset);
  HRESULT hr = S_OK;
  _variant_t* pvtBookmark = NULL;

  if ( _IsEmpty() )
    return ( 0L );

  if ( nPosition < 0 || nPosition > RecordCount() )
		  ThrowAxException(AXLIB_ERROR_INVALID_POS, _T("CAxRecordset::AbsolutePosition"));

  if ( nPosition > 0 )
  {
		pvtBookmark = Bookmark();
    hr = m_piRecordset->put_AbsolutePosition(PositionEnum(nPosition));
		if FAILED( hr )
		{
			if ( pvtBookmark->vt != VT_EMPTY )
				m_piRecordset->put_Bookmark(*pvtBookmark);
		 
		  ThrowAxException(AXLIB_ERROR_NONE, _T("CAxRecordset::AbsolutePosition"), hr);
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -