/****************************************************************************** Copyright (c) 2000 Microsoft Corporation Module Name: Database.cpp Abstract: This file contains the implementation of the JetBlue::Database class. Revision History: Davide Massarenti (Dmassare) 05/17/2000 created ******************************************************************************/ #include #include //////////////////////////////////////////////////////////////////////////////// JetBlue::Database::Database( /*[in]*/ Session* parent , /*[in]*/ JET_SESID sesid , /*[in]*/ LPCSTR szName ) { m_parent = parent; // Session* m_parent; m_sesid = sesid; // JET_SESID m_sesid; m_dbid = JET_dbidNil; // JET_DBID m_dbid; m_strName = szName; // MPC::string m_strName; // TableMap m_mapTables; } JetBlue::Database::~Database() { (void)Close( true ); } //////////////////////////////////////// HRESULT JetBlue::Database::Refresh() { __HCP_FUNC_ENTRY( "JetBlue::Database::Refresh" ); HRESULT hr; JET_OBJECTLIST info; ::ZeroMemory( &info, sizeof(info) ); info.cbStruct = sizeof(info); info.tableid = JET_tableidNil; Table* tblNew = NULL; m_mapTables.clear(); if(m_dbid != JET_dbidNil) { //////////////////////////////////////////////////////////////////////////////// // // Read table definition. // // JET_OBJECTLIST // { // unsigned long cbStruct; // JET_TABLEID tableid; // unsigned long cRecord; // JET_COLUMNID columnidcontainername; // JET_COLUMNID columnidobjectname; // JET_COLUMNID columnidobjtyp; // JET_COLUMNID columniddtCreate; // XXX -- to be deleted // JET_COLUMNID columniddtUpdate; // XXX -- to be deleted // JET_COLUMNID columnidgrbit; // JET_COLUMNID columnidflags; // JET_COLUMNID columnidcRecord; /* Level 2 info */ // JET_COLUMNID columnidcPage; /* Level 2 info */ // }; // // JET_RETRIEVECOLUMN // { // JET_COLUMNID columnid; // void *pvData; // unsigned long cbData; // unsigned long cbActual; // JET_GRBIT grbit; // unsigned long ibLongValue; // unsigned long itagSequence; // JET_COLUMNID columnidNextTagged; // JET_ERR err; // }; JET_RETRIEVECOLUMN rc [1 ]; ::ZeroMemory( &rc, sizeof(rc) ); char tblName[JET_cbNameMost+1]; int i; __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetGetObjectInfo( m_sesid, m_dbid, JET_objtypTable, NULL, NULL, &info, sizeof(info), JET_ObjInfoList )); __MPC_JET_INIT_RETRIEVE_COL( rc, 0, info.columnidobjectname, tblName, JET_cbNameMost ); for(i=0; iLockDatabase( m_strName, fReadOnly ) == false) { __MPC_EXIT_IF_METHOD_FAILS(hr, Close()); __MPC_EXIT_IF_METHOD_FAILS(hr, m_parent->ReleaseDatabase( m_strName )); if(m_parent->LockDatabase( m_strName, fReadOnly ) == false) { __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_BUSY); } } fLocked = true; if(m_dbid == JET_dbidNil) { err = ::JetAttachDatabase( m_sesid, m_strName.c_str(), grbit ); if(err < JET_errSuccess) { if(err == JET_errDatabaseCorrupted && fRepair) { __MPC_EXIT_IF_METHOD_FAILS(hr, Repair()); err = ::JetAttachDatabase( m_sesid, m_strName.c_str(), grbit ); } if(err == JET_errDatabaseCorrupted || fCreate == false) { __MPC_EXIT_IF_JET_FAILS(hr, err); } __MPC_EXIT_IF_JET_FAILS(hr, ::JetCreateDatabase( m_sesid, m_strName.c_str(), NULL, &m_dbid, 0 )); } else { __MPC_EXIT_IF_JET_FAILS(hr, ::JetOpenDatabase( m_sesid, m_strName.c_str(), NULL, &m_dbid, 0 )); } __MPC_EXIT_IF_METHOD_FAILS(hr, Refresh()); } hr = S_OK; __HCP_FUNC_CLEANUP; if(FAILED(hr) && fLocked) { m_parent->UnlockDatabase( m_strName ); } __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Database::Close( /*[in]*/ bool fForce, /*[in]*/ bool fAll ) { __HCP_FUNC_ENTRY( "JetBlue::Database::Close" ); HRESULT hr; JET_ERR err; TableIter it; for(it = m_mapTables.begin(); it != m_mapTables.end(); it++) { Table* tbl = it->second; if(tbl) { HRESULT hr2 = tbl->Close( fForce ); if(!fForce) __MPC_EXIT_IF_METHOD_FAILS(hr, hr2); delete tbl; } } m_mapTables.clear(); if(fAll && m_dbid != JET_dbidNil) { err = ::JetCloseDatabase( m_sesid, m_dbid, 0 ); if(!fForce) __MPC_EXIT_IF_JET_FAILS(hr, err); m_dbid = JET_dbidNil; m_parent->UnlockDatabase( m_strName ); } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Database::Delete( /*[in]*/ bool fForce ) { __HCP_FUNC_ENTRY( "JetBlue::Database::Delete" ); USES_CONVERSION; HRESULT hr; __MPC_EXIT_IF_METHOD_FAILS(hr, Close( fForce )); if(m_strName.length() > 0) { MPC::FileSystemObject fso( A2W( m_strName.c_str() ) ); __MPC_EXIT_IF_METHOD_FAILS(hr, fso.Delete( fForce )); } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } //////////////////////////////////////// HRESULT JetBlue::Database::GetTable( /*[in] */ LPCSTR szName , /*[out]*/ Table*& tbl , /*[in] */ JET_TABLECREATE* pDef ) { __HCP_FUNC_ENTRY( "JetBlue::Database::GetTable" ); HRESULT hr; HRESULT hr2; Table* tblNew = NULL; TableIter it; __MPC_JET_CHECKHANDLE(hr,m_sesid,JET_sesidNil ); if(pDef) szName = pDef->szTableName; it = m_mapTables.find( szName ); if(it == m_mapTables.end()) { __MPC_EXIT_IF_ALLOC_FAILS(hr, tblNew, new Table( m_sesid, m_dbid, szName )); m_mapTables[szName] = tblNew; tbl = tblNew; tblNew = NULL; } else { tbl = it->second; } if(FAILED(hr2 = tbl->Open())) { if(pDef == NULL || hr2 != JetERRToHRESULT( JET_errObjectNotFound )) { __MPC_SET_ERROR_AND_EXIT(hr, hr2); } if(pDef == (JET_TABLECREATE*)-1) { __MPC_EXIT_IF_METHOD_FAILS(hr, tbl->Create()); } else { __MPC_EXIT_IF_METHOD_FAILS(hr, tbl->Create( pDef )); } } hr = S_OK; __HCP_FUNC_CLEANUP; if(tblNew) delete tblNew; __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Database::Compact() { __HCP_FUNC_ENTRY( "JetBlue::Database::Compact" ); HRESULT hr; JET_DBUTIL util; CHAR rgTempDB[MAX_PATH]; ::ZeroMemory( &util, sizeof(util) ); util.cbStruct = sizeof(util); util.sesid = m_sesid; util.op = opDBUTILDBDefragment; util.szDatabase = (LPSTR)m_strName.c_str(); util.szTable = rgTempDB; StringCbPrintfA( rgTempDB, sizeof(rgTempDB), "%s.temp", util.szDatabase ); (void)::DeleteFileA( rgTempDB ); __MPC_EXIT_IF_METHOD_FAILS(hr, Close()); __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetDBUtilities( &util )); __MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::MoveFileExA( rgTempDB, util.szDatabase, MOVEFILE_REPLACE_EXISTING )); hr = S_OK; __HCP_FUNC_CLEANUP; (void)::DeleteFileA( rgTempDB ); __HCP_FUNC_EXIT(hr); } HRESULT JetBlue::Database::Repair() { __HCP_FUNC_ENTRY( "JetBlue::Database::Repair" ); HRESULT hr; JET_DBUTIL util; ::ZeroMemory( &util, sizeof(util) ); util.cbStruct = sizeof(util); util.sesid = m_sesid; util.op = opDBUTILEDBRepair; util.szDatabase = (LPSTR)m_strName.c_str(); __MPC_EXIT_IF_METHOD_FAILS(hr, Close()); __MPC_EXIT_IF_JET_FAILS__MTSAFE(m_sesid, hr, ::JetDBUtilities( &util )); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } //////////////////////////////////////// JetBlue::Table* JetBlue::Database::GetTbl( /*[in]*/ int iPos ) { for(TableIter it = m_mapTables.begin(); it != m_mapTables.end(); it++) { if(iPos-- == 0) return it->second; } return NULL; } JetBlue::Table* JetBlue::Database::GetTbl( LPCSTR szTbl ) { TableIter it = m_mapTables.find( szTbl ); return (it == m_mapTables.end()) ? NULL : it->second; }