|
|
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1999, Microsoft Corp. All rights reserved.
//
// FILE
//
// Database.cpp
//
// SYNOPSIS
//
// Implementation of the CDatabase class. Mainly initialize, compact...
//
// MODIFICATION HISTORY
//
// 02/12/1999 Original version. Thierry Perraut
//
//////////////////////////////////////////////////////////////////////////////
#include "precomp.hpp"
#include "database.h"
#include "msjetoledb.h"
#include "jetoledb.h"
//////////////////////////////////////////////////////////////////////////////
//
// Uninitialize: called at the end by main(), that calls compact()
//
//////////////////////////////////////////////////////////////////////////////
HRESULT CDatabase::Uninitialize (bool bFatalError) { HRESULT hres;
#ifdef THPDEBUG
bFatalError = false; #endif
////////////////////////////////////////
// if a fatal error occured before
////////////////////////////////////////
if (bFatalError) { hres = (m_pITransactionLocal->Abort (NULL, TRUE, FALSE)); TracePrintf ("Fatal Error: import to the database aborted."); } else { hres = (m_pITransactionLocal->Commit (TRUE, XACTTC_SYNC, 0)); #ifdef DEBUG
TracePrintf ("Successful import.\n"); #endif
} ///////////
// Clean
///////////
m_pIOpenRowset->Release(); m_pITransactionLocal->Release(); m_pIDBCreateSession->Release();
////////////////////////////////////////
// compact the DB
////////////////////////////////////////
CHECK_CALL_HRES (Compact());
m_pIDBInitialize->Release();
return hres; }
//////////////////////////////////////////////////////////////////////////////
//
// Compact the database
//
//////////////////////////////////////////////////////////////////////////////
HRESULT CDatabase::Compact () { HRESULT hres;
CHECK_CALL_HRES (m_pIDBInitialize->Uninitialize ()); ///////////////////////////////////////////////
// Set the properties for the data source.
//////////////////////////////////////////////
CComPtr <IDBProperties> l_pIDBProperties;
CHECK_CALL_HRES (m_pIDBInitialize->QueryInterface ( __uuidof (IDBProperties), (void **) &l_pIDBProperties) );
//////////////////////////////////
// Prepare the create session
//////////////////////////////////
DBPROP lprop[2];
VariantInit(&lprop[0].vValue); lprop[0].dwOptions = DBPROPOPTIONS_REQUIRED; lprop[0].dwPropertyID = DBPROP_INIT_DATASOURCE; V_VT (&(lprop[0].vValue)) = VT_BSTR; //////////////////////////////////////////////////////
// put the path to the DB in the property.
// remark: temporaryname was used befire
// but the compacted database will have the name
// that was given as a parameter to that program
//////////////////////////////////////////////////////
V_BSTR (&(lprop[0].vValue)) = SysAllocString (TEMPORARY_FILENAME);
VariantInit(&lprop[1].vValue); lprop[1].dwOptions = DBPROPOPTIONS_REQUIRED; lprop[1].dwPropertyID = DBPROP_INIT_MODE; V_VT (&(lprop[1].vValue)) = VT_I4; V_I4 (&(lprop[1].vValue)) = DB_MODE_READ;
DBPROPSET lPropSet; lPropSet.rgProperties = lprop; lPropSet.cProperties = 2; lPropSet.guidPropertySet = DBPROPSET_DBINIT;
///////////////////////
// Set the properties
///////////////////////
CHECK_CALL_HRES (l_pIDBProperties->SetProperties ( 1, &lPropSet ));
CHECK_CALL_HRES (m_pIDBInitialize->Initialize ());
IJetCompact* l_pIJetCompact; CHECK_CALL_HRES ((m_pIDBInitialize->QueryInterface ( __uuidof (IJetCompact), (void **) &l_pIJetCompact)) );
/////////////////////////////////////////////////////////////
// Prepare the properties for the data dest. (destination)
/////////////////////////////////////////////////////////////
DBPROP lpropDest[1];
VariantInit (&lprop[0].vValue); lpropDest[0].dwOptions = DBPROPOPTIONS_REQUIRED; lpropDest[0].dwPropertyID = DBPROP_INIT_DATASOURCE; V_VT (&(lpropDest[0].vValue)) = VT_BSTR;
///////////////////////////////////////////////////
// Delete the database file if it already existed.
// that should be safe because the temporary DB
// was succesfully created
///////////////////////////////////////////////////
DeleteFileW(mpDBPath.c_str());
//////////////////////////////////////////////
// put the path to the DB in the property.
//////////////////////////////////////////////
V_BSTR (&(lpropDest[0].vValue)) = SysAllocString (mpDBPath.c_str());
DBPROPSET lPropSetDest[1]; lPropSetDest[0].rgProperties = lpropDest; lPropSetDest[0].cProperties = 1; lPropSetDest[0].guidPropertySet = DBPROPSET_DBINIT;
CHECK_CALL_HRES (l_pIJetCompact->Compact(1, lPropSetDest)); /////////////
// Clean
/////////////
CHECK_CALL_HRES (m_pIDBInitialize->Uninitialize()); ////////////////////////////////////////////
//result not checked: that's not important
////////////////////////////////////////////
DeleteFileW(TEMPORARY_FILENAME); SysFreeString( V_BSTR (&(lpropDest[0].vValue)) ); SysFreeString( V_BSTR (&(lprop[0].vValue)) );
// The CHECK_CALL_HRES set the value of hres
return hres; }
// ///////////////////////////////////////////////////////////////////////////
//
// InitializeDB
//
// Comes from the file \ias\devtest\services\dictionary\dnary\dnarydump.cpp
//
// ///////////////////////////////////////////////////////////////////////////
HRESULT CDatabase::InitializeDB(WCHAR * pDatabasePath) { CLSID clsid; HRESULT hres;
////////////////////////////////////////////////////
// Retrieve the classID for the jet 4.0 provider
////////////////////////////////////////////////////
CHECK_CALL_HRES( CLSIDFromProgID ( OLESTR ("Microsoft.Jet.OLEDB.4.0"), &clsid //Pointer to the CLSID
) );
////////////////////////////////////
// init: init the provider directly
////////////////////////////////////
CHECK_CALL_HRES( CoCreateInstance ( clsid, NULL, CLSCTX_INPROC_SERVER, __uuidof (IDBInitialize), (void **) &m_pIDBInitialize ) );
mpDBPath = pDatabasePath;
//////////////////////////////////////////////
// Set the properties for the data source.
//////////////////////////////////////////////
CComPtr <IDBProperties> pIDBProperties;
CHECK_CALL_HRES( m_pIDBInitialize->QueryInterface( __uuidof (IDBProperties), (void **) &pIDBProperties ) );
///////////////////////////////
// Prepare the create session
///////////////////////////////
DBPROP lprop[2];
VariantInit (&lprop[0].vValue); lprop[0].dwOptions = DBPROPOPTIONS_REQUIRED; lprop[0].dwPropertyID = DBPROP_INIT_DATASOURCE; V_VT (&(lprop[0].vValue)) = VT_BSTR;
//////////////////////////////////////////////
// put the path to the DB in the property.
// this is the temporary filename
//////////////////////////////////////////////
V_BSTR (&(lprop[0].vValue)) = SysAllocString (TEMPORARY_FILENAME); VariantInit(&lprop[1].vValue); lprop[1].dwOptions = DBPROPOPTIONS_REQUIRED; lprop[1].dwPropertyID = DBPROP_INIT_MODE; V_VT (&(lprop[1].vValue)) = VT_I4; V_I4 (&(lprop[1].vValue)) = DB_MODE_READWRITE;
DBPROPSET lPropSet; lPropSet.rgProperties = lprop; lPropSet.cProperties = 2; lPropSet.guidPropertySet = DBPROPSET_DBINIT;
// Set the properties
CHECK_CALL_HRES(pIDBProperties->SetProperties (1, &lPropSet));
////////////////////
// Lock properties
////////////////////
DBPROP dbpropb[1]; dbpropb[0].dwPropertyID = DBPROP_JETOLEDB_DATABASELOCKMODE; dbpropb[0].dwOptions = DBPROPOPTIONS_REQUIRED; dbpropb[0].colid = DB_NULLID; dbpropb[0].vValue.vt = VT_I4; dbpropb[0].vValue.lVal = DBPROPVAL_DL_OLDMODE;
DBPROPSET dbpropSetb; dbpropSetb.guidPropertySet = DBPROPSET_JETOLEDB_DBINIT; dbpropSetb.cProperties = 1; dbpropSetb.rgProperties = dbpropb;
// Set the properties
CHECK_CALL_HRES (pIDBProperties->SetProperties(1, &dbpropSetb));
CHECK_CALL_HRES (m_pIDBInitialize->Initialize ());
CHECK_CALL_HRES( m_pIDBInitialize->QueryInterface( __uuidof (IDBCreateSession), (void **) &m_pIDBCreateSession ) );
CHECK_CALL_HRES( m_pIDBCreateSession->CreateSession ( NULL, // pUnkOuter
__uuidof (IOpenRowset), (IUnknown **) & m_pIOpenRowset ) );
CHECK_CALL_HRES( m_pIOpenRowset->QueryInterface ( __uuidof (ITransactionLocal), (PVOID *) & m_pITransactionLocal ) );
//////////////////////////////////////////////
// start a transaction
// everything is "under" that transaction
//////////////////////////////////////////////
CHECK_CALL_HRES( m_pITransactionLocal->StartTransaction ( ISOLATIONLEVEL_READUNCOMMITTED, 0, NULL, NULL ) );
////////////////////////////
// prepare the properties
////////////////////////////
mlrgProperties[0].dwPropertyID = DBPROP_IRowsetChange; mlrgProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED; mlrgProperties[0].colid = DB_NULLID; VariantInit(&mlrgProperties[0].vValue); V_VT (&(mlrgProperties[0].vValue)) = VT_BOOL; V_BOOL (&(mlrgProperties[0].vValue)) = VARIANT_TRUE;
mlrgProperties[1].dwPropertyID = DBPROP_UPDATABILITY; mlrgProperties[1].dwOptions = DBPROPOPTIONS_REQUIRED; mlrgProperties[1].colid = DB_NULLID; VariantInit (&mlrgProperties[1].vValue); V_VT (&(mlrgProperties[1].vValue)) = VT_I4; V_I4 (&(mlrgProperties[1].vValue)) = DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_DELETE | DBPROPVAL_UP_INSERT;
mlrgPropSets->rgProperties = mlrgProperties; mlrgPropSets->cProperties = 2; mlrgPropSets->guidPropertySet = DBPROPSET_ROWSET;
SysFreeString(V_BSTR (&(lprop[0].vValue)));
return hres; }
// ///////////////////////////////////////////////////////////////////////////
//
// InitializeRowset
//
// ///////////////////////////////////////////////////////////////////////////
HRESULT CDatabase::InitializeRowset(WCHAR * pTableName, IRowset ** ppRowset) { //Create the tableID
mTableID.eKind = DBKIND_NAME; mTableID.uName.pwszName = pTableName;
//Open the (defined by parameters) rowset
return m_pIOpenRowset->OpenRowset( NULL, &mTableID, NULL, __uuidof (IRowset), 1, mlrgPropSets, (IUnknown **) ppRowset ); }
|