ClearBox Server v1.2 Developer's Guide |
Step 5. Implementing Database ConnectionOn this step we create a class that encapsulates database connection. It uses ATL OLE DB templates to get access to OLE DB providers for MS Access, MS SQL and ODBC data sources. 1. Create a new class. Select Project -> Add Class... from the main menu, select Generic C++ Class and click Open. Name this class CDB and click Finish. 2. Double-click CDB class in the Class View window. Class declaration is opened. Add a private member m_Session with CSession type and add manually a public function that returns a reference to this variable: class CDB { public: CDB(void); ~CDB(void); CSession& Session() { return m_Session; } private: CSession m_Session; }; This variable stores actual connection to a data source. 2. Right-click CDB class in Class View and through a Add Variable wizard add a function with void return type, public access and CloseSession name without any parameters. Find its empty definition and replace it with the following code: void CDB::CloseSession(void) { if (m_Session.m_spOpenRowset!=NULL) m_Session.Close(); }
CDB::~CDB(void) { CloseSession(); } 3. With a class wizard add a new method to CDB class with void return type, public access type, FormatErrors name and CString& errStr argument. Change its body to the following code: void CDB::FormatErrors(CString& errStr) { USES_CONVERSION; CDBErrorInfo errInfo; DWORD numRecords; HRESULT hRes=errInfo.GetErrorRecords(&numRecords); if (FAILED(hRes) || hRes == S_FALSE || numRecords == 0) return; LCID lcid = GetUserDefaultLCID(); CComBSTR str; CComPtr 4. Add a new method with the following parameters:
Replace its bode with the following code: bool CDB::OpenMSAccess(CString dbPath) { CDataSource db; CDBPropSet dbinit(DBPROPSET_DBINIT); CloseSession(); dbinit.AddProperty(DBPROP_INIT_DATASOURCE, dbPath); HRESULT hr=db.Open(_T("Microsoft.Jet.OLEDB.4.0"), &dbinit); if (FAILED(hr)) return false; return m_Session.Open(db)==S_OK; } This code opens a data source represented by Microsoft.Jet.OLEDB.4.0 OLE DB provider and on success establishes a session with it. The method will be used to connect to MS Access databases. 5. Add a new method with the following parameters:
Replace its bode with the following code: bool CDB::OpenODBC(CString dsn, CString dbUser, CString dbPassword) { USES_CONVERSION; CDataSource db; CloseSession(); CString connStr; connStr.Format(_T("Provider=MSDASQL;Data Source=%s;UID=%s;PWD=%s"), dsn,dbUser,dbPassword); HRESULT hr=db.OpenFromInitializationString(CT2W(connStr)); if (FAILED(hr)) return false; return m_Session.Open(db)==S_OK; } This method opens a connection with ODBC data source with specified DSN, user name and password. 6. Add a new method with the following parameters:
Replace its declaration with the following code: bool CDB::OpenMSSQL(CString dbServer, CString dbCatalog, CString dbUser, CString dbPassword, bool winAuthen) { USES_CONVERSION; CloseSession(); CDataSource db; CDBPropSet dbinit(DBPROPSET_DBINIT); if (!winAuthen) { dbinit.AddProperty(DBPROP_AUTH_PASSWORD, dbPassword); dbinit.AddProperty(DBPROP_AUTH_USERID, dbUser); } else dbinit.AddProperty(DBPROP_AUTH_INTEGRATED, OLESTR("SSPI")); dbinit.AddProperty(DBPROP_INIT_CATALOG, dbCatalog); dbinit.AddProperty(DBPROP_INIT_DATASOURCE, dbServer); HRESULT hr = db.Open(L"SQLOLEDB.1", &dbinit); if (FAILED(hr)) return false; return m_Session.Open(db)==S_OK; } This method uses native MS SQL OLE provider to establish connection with a server. 7. By this point we've created all methods of this class. Let's add a variable to CExtension class. With a wizard add a variable to CExtension class with private access type, CDB type and m_DB name. 8. Finally, we should open a connection to a database during server extension initialization. It's necessary if user is authenticated through a database or accounting records are written to the database. Double-click InitializeEx subnode of CExtension class in Class View. Change this method implementation so it should look like the following: STDMETHOD(InitializeEx)(VARIANT_BOOL start, IServer * pServer) { if (start==VARIANT_TRUE) { m_pServ2=pServer; m_pLivAcct=pServer; m_pCSVAcct=pServer; if (!ReadAuthenticationSettings()) return E_INVALIDARG; if (!ReadAuthenMethodsSettings()) return E_INVALIDARG; if (!ReadAccountingSettings()) return E_INVALIDARG; if (m_AuthenType==db || m_AcctMethod==database) { bool res=true; switch(m_DBType) { case access: if (!m_DB.OpenMSAccess(m_DBPath)) res=false; break; case mssql: if (!m_DB.OpenMSSQL(m_DBServer,m_DBCatalog, m_DBUser,m_DBPassword,m_bUseNTSecurity)) res=false; break; case odbc: if (!m_DB.OpenODBC(m_DSN,m_DBUser,m_DBPassword)) res=false; break; }; if (!res) { CString s; m_DB.FormatErrors(s); m_pServ2->LogExtensionError(E_FAIL,(LPCTSTR)s); return E_FAIL; } } HRESULT hr=AdjustPrivileges(); if (FAILED(hr)) return hr; } return S_OK; } AdjustPrivileges function will be created in the next tutorial step.
© 2001-2003 XPerience Technologies. www.xperiencetech.com |
Created by chm2web html help conversion utility. |