/****************************************************************************** Copyright (c) 2000 Microsoft Corporation Module Name: Table.cpp Abstract: This file contains the implementation of the JetBlue::Table class. Revision History: Davide Massarenti (Dmassare) 05/17/2000 created ******************************************************************************/ #include //////////////////////////////////////////////////////////////////////////////// static HRESULT AdjustReturnCode( HRESULT hr, bool *pfFound ) { if(pfFound) { if(hr == JetBlue::JetERRToHRESULT(JET_errNoCurrentRecord) || hr == JetBlue::JetERRToHRESULT(JET_errRecordNotFound ) ) { hr = S_OK; *pfFound = false; } else { *pfFound = (SUCCEEDED(hr)) ? true : false; } } return hr; } //////////////////////////////////////////////////////////////////////////////// JetBlue::Table::Table() { m_sesid = JET_sesidNil; // JET_SESID m_sesid; m_dbid = JET_dbidNil; // JET_DBID m_dbid; m_tableid = JET_tableidNil; // JET_TABLEID m_tableid; // MPC::string m_strName; // ColumnVector m_vecColumns; // IndexVector m_vecIndexes; m_idxSelected = NULL; // Index* m_idxSelected; // Column m_fakeCol; // Index m_fakeIdx; } JetBlue::Table::Table( /*[in]*/ JET_SESID sesid , /*[in]*/ JET_DBID dbid , /*[in]*/ LPCSTR szName ) { m_sesid = sesid; // JET_SESID m_sesid; m_dbid = dbid; // JET_DBID m_dbid; m_tableid = JET_tableidNil; // JET_TABLEID m_tableid; m_strName = szName; // MPC::string m_strName; // ColumnVector m_vecColumns; // IndexVector m_vecIndexes; m_idxSelected = NULL; // Index* m_idxSelected; // Column m_fakeCol; // Index m_fakeIdx; } JetBlue::Table::~Table() { (void)Close( true ); } //////////////////////////////////////// HRESULT JetBlue::Table::Duplicate( /*[in]*/ Table& tbl ) { __HCP_FUNC_ENTRY( "JetBlue::Table::Duplicate" ); HRESULT hr; int iColMax = tbl.m_vecColumns.size(); int iIdxMax = tbl.m_vecIndexes.size(); int iCol; int iIdx; m_sesid = tbl.m_sesid; // JET_SESID m_sesid; m_dbid = tbl.m_dbid; // JET_DBID m_dbid; m_tableid = JET_tableidNil; // JET_TABLEID m_tableid; m_strName.erase(); // MPC::string m_strName; m_vecColumns.resize( iColMax ); // ColumnVector m_vecColumns; m_vecIndexes.resize( iIdxMax ); // IndexVector m_vecIndexes; // Column m_fakeCol; // Index m_fakeIdx; __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetDupCursor( m_sesid, tbl.m_tableid, &m_tableid, 0 )); // // Copy the columns and indexes, updating the tableid. // for(iCol=0; iColm_strName != idxName) { iCol = 0; idx = &m_vecIndexes[iIdx++]; idx->m_sesid = m_sesid; idx->m_tableid = m_tableid; idx->m_strName = idxName; idx->m_grbitIndex = grbit; idx->m_cKey = cKey; idx->m_cEntry = cEntry; idx->m_cPage = cPage; idx->m_vecColumns.resize( cColumn ); } col = &idx->m_vecColumns[iCol++]; col->m_sesid = m_sesid; col->m_tableid = m_tableid; col->m_strName = colName; col->m_coldef.columnid = colDef.columnid; col->m_coldef.coltyp = colDef.coltyp; col->m_coldef.wCountry = colDef.wCountry; col->m_coldef.langid = colDef.langid; col->m_coldef.cp = colDef.cp; col->m_coldef.wCollate = colDef.wCollate; col->m_coldef.cbMax = colDef.cbMax; col->m_coldef.grbit = colDef.grbit; } m_vecIndexes.resize( iIdx ); // Trim down the size to the real one. } } hr = S_OK; __HCP_FUNC_CLEANUP; if(infoCols.tableid != JET_tableidNil) { __MPC_JET__MTSAFE_NORESULT(m_sesid, ::JetCloseTable( m_sesid, infoCols.tableid )); } if(infoIdxs.tableid != JET_tableidNil) { __MPC_JET__MTSAFE_NORESULT(m_sesid, ::JetCloseTable( m_sesid, infoIdxs.tableid )); } __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::Close( /*[in]*/ bool fForce ) { __HCP_FUNC_ENTRY( "JetBlue::Table::Close" ); HRESULT hr; if(m_tableid != JET_tableidNil) { JET_ERR err = ::JetCloseTable( m_sesid, m_tableid ); if(!fForce) __MPC_EXIT_IF_JET_FAILS(hr, err); m_tableid = JET_tableidNil; } m_idxSelected = NULL; m_vecColumns.clear(); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } //////////////////////////////////////// HRESULT JetBlue::Table::Attach( /*[in]*/ JET_TABLEID tableid ) { __HCP_FUNC_ENTRY( "JetBlue::Table::Attach" ); HRESULT hr; __MPC_EXIT_IF_METHOD_FAILS(hr, Close()); m_tableid = tableid; __MPC_EXIT_IF_METHOD_FAILS(hr, Refresh()); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::Open() { __HCP_FUNC_ENTRY( "JetBlue::Table::Open" ); HRESULT hr; if(m_tableid == JET_tableidNil) { __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetOpenTable( m_sesid, m_dbid, m_strName.c_str(), NULL, 0, JET_bitTableUpdatable, &m_tableid )); __MPC_EXIT_IF_METHOD_FAILS(hr, Refresh()); } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::Create() { __HCP_FUNC_ENTRY( "JetBlue::Table::Create" ); HRESULT hr; if(m_tableid == JET_tableidNil) { __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetCreateTable( m_sesid, m_dbid, m_strName.c_str(), 10, 80, &m_tableid )); __MPC_EXIT_IF_METHOD_FAILS(hr, Refresh()); } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::Create( /*[in]*/ JET_TABLECREATE* pDef ) { __HCP_FUNC_ENTRY( "JetBlue::Table::Create" ); HRESULT hr; JET_TABLECREATE tbldef = *pDef; __MPC_EXIT_IF_METHOD_FAILS(hr, Close()); tbldef.szTableName = (LPSTR)m_strName.c_str(); __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetCreateTableColumnIndex( m_sesid, m_dbid, &tbldef )); m_tableid = tbldef.tableid; __MPC_EXIT_IF_METHOD_FAILS(hr, Refresh()); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::Delete( /*[in]*/ bool fForce ) { __HCP_FUNC_ENTRY( "JetBlue::Table::Delete" ); HRESULT hr; __MPC_EXIT_IF_METHOD_FAILS(hr, Close( fForce )); if(m_strName.length() > 0) { __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetDeleteTable( m_sesid, m_dbid, m_strName.c_str() )); } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } //////////////////////////////////////// HRESULT JetBlue::Table::DupCursor( /*[in/out]*/ Cursor& cur ) { __HCP_FUNC_ENTRY( "JetBlue::Table::DupCursor" ); HRESULT hr; __MPC_JET_CHECKHANDLE(hr,m_sesid ,JET_sesidNil ); __MPC_JET_CHECKHANDLE(hr,m_tableid,JET_tableidNil); __MPC_EXIT_IF_METHOD_FAILS(hr, cur->Duplicate( *this )); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::SelectIndex( /*[in]*/ LPCSTR szIndex , /*[in]*/ JET_GRBIT grbit ) { __HCP_FUNC_ENTRY( "JetBlue::Table::SelectIndex" ); HRESULT hr; int iPos; Index* idxSelected; __MPC_JET_CHECKHANDLE(hr,m_sesid ,JET_sesidNil ); __MPC_JET_CHECKHANDLE(hr,m_tableid,JET_tableidNil); iPos = GetIdxPosition( szIndex ); if(iPos == -1) { __MPC_SET_ERROR_AND_EXIT(hr, JetBlue::JetERRToHRESULT(JET_errIndexNotFound)); } idxSelected = &(m_vecIndexes[iPos]); if(grbit == JET_bitNoMove) { if(m_idxSelected == idxSelected) { // // No need to reselect it. // __MPC_SET_ERROR_AND_EXIT(hr, S_OK); } // // There was no index selected, so there's no current record... // grbit = JET_bitMoveFirst; } __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetSetCurrentIndex2( m_sesid, m_tableid, szIndex, grbit )); m_idxSelected = idxSelected; hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::SetIndexRange( /*[in]*/ JET_GRBIT grbit ) { __HCP_FUNC_ENTRY( "JetBlue::Table::SetIndexRange" ); HRESULT hr; __MPC_JET_CHECKHANDLE(hr,m_sesid ,JET_sesidNil ); __MPC_JET_CHECKHANDLE(hr,m_tableid ,JET_tableidNil); __MPC_JET_CHECKHANDLE(hr,m_idxSelected,NULL ); __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetSetIndexRange( m_sesid, m_tableid, grbit )); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::PrepareInsert() { __HCP_FUNC_ENTRY( "JetBlue::Table::PrepareInsert" ); HRESULT hr; __MPC_JET_CHECKHANDLE(hr,m_sesid ,JET_sesidNil ); __MPC_JET_CHECKHANDLE(hr,m_tableid,JET_tableidNil); __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetPrepareUpdate( m_sesid, m_tableid, JET_prepInsert )); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::PrepareUpdate() { __HCP_FUNC_ENTRY( "JetBlue::Table::PrepareUpdate" ); HRESULT hr; __MPC_JET_CHECKHANDLE(hr,m_sesid ,JET_sesidNil ); __MPC_JET_CHECKHANDLE(hr,m_tableid,JET_tableidNil); __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetPrepareUpdate( m_sesid, m_tableid, JET_prepReplace )); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::CancelChange() { __HCP_FUNC_ENTRY( "JetBlue::Table::CancelChange" ); HRESULT hr; __MPC_JET_CHECKHANDLE(hr,m_sesid ,JET_sesidNil ); __MPC_JET_CHECKHANDLE(hr,m_tableid,JET_tableidNil); __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetPrepareUpdate( m_sesid, m_tableid, JET_prepCancel )); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::Move( /*[in]*/ JET_GRBIT grbit , /*[in]*/ long cRow , /*[in]*/ bool *pfFound ) { __HCP_FUNC_ENTRY( "JetBlue::Table::Move" ); HRESULT hr; __MPC_JET_CHECKHANDLE(hr,m_sesid ,JET_sesidNil ); __MPC_JET_CHECKHANDLE(hr,m_tableid,JET_tableidNil); __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetMove( m_sesid, m_tableid, cRow, grbit )); hr = S_OK; __HCP_FUNC_CLEANUP; hr = AdjustReturnCode( hr, pfFound ); __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::Seek( /*[in]*/ JET_GRBIT grbit , /*[in]*/ VARIANT* rgKeys , /*[in]*/ int iLen , /*[in]*/ bool *pfFound ) { __HCP_FUNC_ENTRY( "JetBlue::Table::Seek" ); HRESULT hr; int iPos; __MPC_JET_CHECKHANDLE(hr,m_sesid ,JET_sesidNil ); __MPC_JET_CHECKHANDLE(hr,m_tableid ,JET_tableidNil); __MPC_JET_CHECKHANDLE(hr,m_idxSelected,NULL ); if(iLen != m_idxSelected->NumOfColumns()) { __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG); } for(iPos=0; iPosGetCol( iPos ).Put( rgKeys[iPos], iPos )); } __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetSeek( m_sesid, m_tableid, grbit )); hr = S_OK; __HCP_FUNC_CLEANUP; hr = AdjustReturnCode( hr, pfFound ); __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::Get( /*[in]*/ int iArg , /*[out]*/ CComVariant* rgArg ) { __HCP_FUNC_ENTRY( "JetBlue::Table::Get" ); HRESULT hr; ColumnIter it; __MPC_JET_CHECKHANDLE(hr,m_sesid ,JET_sesidNil ); __MPC_JET_CHECKHANDLE(hr,m_tableid,JET_tableidNil); for(it = m_vecColumns.begin(); it != m_vecColumns.end() && iArg > 0; it++, iArg--, rgArg++) { __MPC_EXIT_IF_METHOD_FAILS(hr, it->Get( *rgArg )); } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::Put( /*[in]*/ int iArg , /*[in]*/ const CComVariant* rgArg ) { __HCP_FUNC_ENTRY( "JetBlue::Table::Put" ); HRESULT hr; ColumnIter it; __MPC_JET_CHECKHANDLE(hr,m_sesid ,JET_sesidNil ); __MPC_JET_CHECKHANDLE(hr,m_tableid,JET_tableidNil); for(it = m_vecColumns.begin(); it != m_vecColumns.end() && iArg > 0; it++, iArg--, rgArg++) { __MPC_EXIT_IF_METHOD_FAILS(hr, it->Put( *rgArg )); } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::UpdateRecord( /*[in]*/ bool fMove ) { __HCP_FUNC_ENTRY( "JetBlue::Table::UpdateRecord" ); HRESULT hr; __MPC_JET_CHECKHANDLE(hr,m_sesid ,JET_sesidNil ); __MPC_JET_CHECKHANDLE(hr,m_tableid,JET_tableidNil); if(fMove) { BYTE rgBookmark[JET_cbBookmarkMost]; unsigned long cbActual; __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetUpdate ( m_sesid, m_tableid, rgBookmark, sizeof(rgBookmark), &cbActual )); __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetGotoBookmark( m_sesid, m_tableid, rgBookmark , cbActual )); } else { __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetUpdate( m_sesid, m_tableid, NULL, 0, NULL )); } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Table::DeleteRecord() { __HCP_FUNC_ENTRY( "JetBlue::Table::DeleteRecord" ); HRESULT hr; __MPC_JET_CHECKHANDLE(hr,m_sesid ,JET_sesidNil ); __MPC_JET_CHECKHANDLE(hr,m_tableid,JET_tableidNil); __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetDelete( m_sesid, m_tableid )); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } //////////////////////////////////////// int JetBlue::Table::GetColPosition( /*[in]*/ LPCSTR szCol ) { int iLen = m_vecColumns.size(); int iPos; for(iPos=0; iPos