/**********************************************************************
**
** File name : OLEDatabase.cpp
**
** Contents : Database routines to access OLEDB
**
**********************************************************************/
#include "stdafx.h"
#include "OLEDatabase.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//
// Constructor
//
COLEDatabase::COLEDatabase()
{
m_bOpen = FALSE ;
// Not Open
m_bSQL = FALSE ;
// Not SQL DB
m_bExclusive = FALSE ; // Not Exclusive
Mode
m_bReadOnly = FALSE ; // Not Read
Only
}
//
// Destructor
//
COLEDatabase::~COLEDatabase()
{
Close();
//
Make sure it's closed
}
//
// Format a Date Time for the type of DB open
//
CString COLEDatabase::FormatDateTime( COleDateTime &ts )
{
CString csResult ;
if ( m_bSQL )
csResult = ts.Format( _T( "'%Y-%m-%d
%H:%M:%S'" ) ) ;
else
csResult.Format( _T( "%f" ), ts ) ;
return csResult ;
}
//
// Return the function to convert a DB field to upper case
//
const TCHAR *COLEDatabase::UpperCaseFunction()
{
if ( m_bSQL )
return _T( "UPPER" ) ;
return _T( "UCase" ) ;
}
//
// return either the pathname of the Access DB
// or >Server>Database for SQL
//
CString COLEDatabase::GetFullPath()
{
CString csPath ;
if ( IsSQL() )
csPath.Format( _T( ">%s>%s" ) ,
m_csServerName, m_csDatabase ) ;
else
csPath = m_csDatabase ;
return csPath ;
}
//
// Open the database
//
void COLEDatabase::Open(LPCTSTR lpszName, BOOL bExclusive, BOOL bReadOnly , LPCTSTR
lpszPassword )
{
// Close first, in case still open
CloseConnection();
if ( *lpszName == '>' )
//
SQL ?
{
//
Yes
TCHAR szPath[ _MAX_PATH ] ;
strscpy( szPath, lpszName+1 ) ;
TCHAR *pSplit = strchr( szPath, '>' ) ;
// Find Database
if ( pSplit )
//
Found ?
{
//
yes
*pSplit = '\0' ;
//
separate
m_csServerName = szPath
;
//
And save Server
m_csDatabase = pSplit+1
;
//
plus database
m_bSQL = TRUE ;
//
Flag SQL
}
}
else
{
m_csServerName = "" ;
//
Access - No Server
m_csDatabase = lpszName ;
//
save path to DB
m_bSQL = FALSE ;
//
Not SQL
}
//
// try and open the database
//
try
{
if ( m_bSQL )
OpenSQLConnection(
bExclusive, bReadOnly ) ; // No password on SQL
else
{
OpenJETConnection(
bExclusive,
bReadOnly,
lpszPassword
) ; // All options
}
// Open sessions
HRESULT hr = m_Session.Open(m_DB);
//
Now open the session
if (FAILED(hr))
//
ok ?
throw new
COLEDBException(m_Session, hr); // no
m_bOpen = TRUE ;
//
now open
}
catch (CException* pException)
{
CloseConnection();
//
In case half open
throw pException;
//
Throw to next handler
}
}
//
// Close the database
//
void COLEDatabase::Close()
{
// Close the local database
if ( m_bOpen )
//
Open ?
{
//
Yes
if ( m_bExclusive )
//
Exclusive mode ?
{
//
Yes
m_bExclusive = FALSE ;
//
Not any more !
if ( m_bSQL )
//
SQL ?
{
//
Yes
//
//
Execute the sp_dboption stored procedure
//
to disable single user mode
//
CNoRecordSetSQLCommand
cRS ;
LONG
lRowsAffected = 0 ;
CString
csSQL ;
csSQL.Format(
"EXECUTE sp_dboption '%s','single user','false'",
(
const TCHAR * )m_csDatabase ) ;
HRESULT
hr = cRS.Execute( m_Session, csSQL , &lRowsAffected ) ;
if
( FAILED(hr) )
throw
( new COLEDBException( m_Session, hr ) ) ;
}
}
m_bOpen = FALSE ;
//
Not Open
m_bReadOnly = FALSE ;
//
Not Read only
CloseConnection() ;
//
Close the connection
}
}
//
// Execute some SQL on the database
//
LONG COLEDatabase::Execute(LPCTSTR lpszSQL, int nOptions)
{
UNUSED( nOptions ) ;
//
// A general SQL command that returns no rows
//
CGeneralSQLCommand SQLCmd ;
LONG lRowsAffected = 0 ;
try
{
SQLCmd.Open( m_Session, lpszSQL,
&lRowsAffected ) ;
}
catch ( CException *e )
{
e->Delete() ;
lRowsAffected = -1 ;
}
return lRowsAffected ;
}
//
// Get the number of records affected from the last execute
//
VOID_ COLEDatabase::CloseConnection( VOID_ )
{
m_Session.Close();
// Close the session
m_DB.Close();
//
Close the DB
}
//
// Open the database connections (NOTE - this method will throw an COLDBException)
//
VOID_ COLEDatabase::OpenSQLConnection( BOOL bExclusive, BOOL bReadOnly )
{
// Build properties
CDBPropSet dbinit;
// Initialisation properties
dbinit.SetGUID(DBPROPSET_DBINIT);
dbinit.AddProperty(DBPROP_AUTH_INTEGRATED, _T("SSPI"));
dbinit.AddProperty(DBPROP_INIT_CATALOG, m_csDatabase );
dbinit.AddProperty(DBPROP_INIT_DATASOURCE, m_csServerName ) ;
if ( bReadOnly )
dbinit.AddProperty(DBPROP_INIT_MODE,
(long)DB_MODE_READ ) ;
HRESULT hr = m_DB.Open( _T( "SQLOLEDB" ), &dbinit, 1);
if (FAILED(hr))
//
Open ok ?
throw new COLEDBException( m_DB, hr);
// No - throw an exception
if ( bExclusive )
//
Exclusive mode ?
{
//
Yes
//
// Execute the sp_dboption stored procedure
//
CSession session ;
session.Open( m_DB ) ;
CNoRecordSetSQLCommand cRS ;
LONG lRowsAffected = 0 ;
CString csSQL ;
csSQL.Format( "EXECUTE sp_dboption
'%s','single user','true'",
(
const TCHAR * )m_csDatabase ) ;
HRESULT hr = cRS.Execute( session, csSQL,
&lRowsAffected ) ;
if (FAILED(hr))
//
Ok ?
{
//
No
Close() ;
throw (new
COLEDBException(session, hr));
}
session.Close() ;
}
m_bExclusive = bExclusive ;
//
Set attributes
m_bReadOnly = bReadOnly ;
}
//
// Open the database connections (NOTE - this method will throw an COLDBException)
//
VOID_ COLEDatabase::OpenJETConnection( BOOL bExclusive, BOOL bReadOnly, LPCTSTR
lpszPassword )
{
//
// Build properties
//
CDBPropSet dbinit[2];
// Standard DBINIT properties
dbinit[0].SetGUID(DBPROPSET_DBINIT);
dbinit[0].AddProperty(DBPROP_AUTH_CACHE_AUTHINFO, true);
dbinit[0].AddProperty(DBPROP_AUTH_ENCRYPT_PASSWORD, false);
dbinit[0].AddProperty(DBPROP_INIT_DATASOURCE, m_csDatabase ) ;
// Set Jet OLE DB provider specific properties
dbinit[1].SetGUID(DBPROPSET_JETOLEDB_DBINIT);
if ( bExclusive || bReadOnly )
{
long lMask = 0 ;
if ( bExclusive )
lMask |=
DB_MODE_SHARE_EXCLUSIVE ; // Fully exclusive
if ( bReadOnly )
lMask |= DB_MODE_READ ;
//
Read Only
dbinit[0].AddProperty(DBPROP_INIT_MODE, lMask )
;
}
if ( lpszPassword )
//
Password ?
{
//Database password
dbinit[1].AddProperty(DBPROP_JETOLEDB_DATABASEPASSWORD,
lpszPassword );
}
if ( !bReadOnly )
{
//Database Locking Mode - set to row locking !
dbinit[1].AddProperty(DBPROP_JETOLEDB_DATABASELOCKMODE,
(long)DBPROPVAL_DL_ALCATRAZ ) ;
}
else
{
// No Locking
dbinit[1].AddProperty(DBPROP_JETOLEDB_MAXLOCKSPERFILE,
0L ) ;
}
HRESULT hr = m_DB.Open(_T("Microsoft.JET.OLEDB.4.0"), dbinit,
2);
if (FAILED(hr))
{
throw new COLEDBException( m_DB, hr);
}
m_bExclusive = bExclusive ;
m_bReadOnly = bReadOnly ;
}