Solved

Connection Pooling Using CDatabase

Posted on 2004-04-13
8
939 Views
Last Modified: 2013-11-20
I was trying to setup Connection Pooling on an existing MFC based application.
The backend is Oracle and I used CRecordset to get access to the data.

I followed an article on the Codeguru website..  http://www.codeguru.com/Cpp/data/mfc_database/odbc/article.php/c1149/

I followed the steps written in it ( listed below), but, I have questions about how to accomplish 3 of them....
done. 1. Create (or download) the CDatabase-derived class, and add it to your Project
done. 2. Create a member of the CDatabase-derived class in your CWinApp-derived (Application) class
done. 3. Create a SQLHANDLE data member in your Application class for the Enviroment Handle
??..    4. Add an accessor function that returns the address of the CDatabase-derived member you added in the previous step
??..    5. Make the necessary SQLSetEnvAttr(...) and SQLAllocHandle(...) calls as specified above
done. 6. Initially open your CDatabase-derived object (if you are using SQL Authentication)
??      7. Whenever you instantiate a CRecordset-derived object, pass the address of the CDatabase-derived class into its constructor

First of all,
1) If this is one of the better ways to accomplish Connection pooling, please advise on how to complete this based on code snippets below.
2)If there's another way of doing this (I have 20 tables), please step through. I cant say I'm good at this and any help is greatly appreciated.



Here's my code in snippets from different files.

----------- CCPDatabase class.. as is from article.Wrapper class across CDatabase

class      CCPDatabase : public CDatabase
{
public:
      /**/                  CCPDatabase()
      {
      };
      //
      //      Code Is Copied From CDatabase Source Code...
      //
      virtual      BOOL      OpenEx( LPCTSTR lpszConnectString, DWORD dwOptions = 0 )
      {
            dwOptions |= noOdbcDialog;                                          // Force NoDialog
                              .....
                             .....
}

}
--------------------------------------------------------------------

-----------------MyWinApp Class

::InitInstance
{
      // Setup the Connection Pool
      //   m_shSQLEnv Is A SQLHANDLE Member That Must Be Freed When Your
      //   Application Terminated
      //
            SQLRETURN srRetCode = 0;
            srRetCode = SQLSetEnvAttr( NULL, SQL_ATTR_CONNECTION_POOLING,
                        (SQLPOINTER)SQL_CP_ONE_PER_DRIVER, 0 );                  // Enable Connection Pooling
            srRetCode = SQLAllocHandle( SQL_HANDLE_ENV, NULL, &m_shSQLEnv ); // Get Global Handle
      // End setup of Connection Pool


      // ****************************************************************
      // Calling the CDatabase Open function for the first and ONLY time
      // ****************************************************************
   if( !m_shPDB.IsOpen( ) &&
       !m_shPDB.OpenEx( NULL ) )
      return FALSE;
      // **********return false on fail***********************************

}
-------------------------------------------------------------------------------------------------------------------
---------------------------- One of my CRecordsets.CPP file
// DetailSet.cpp : implementation file
//

#include "stdafx.h"
#include "MyWinApp.h"
#include "DetailSet.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDetailSet

IMPLEMENT_DYNAMIC(CDetailSet, CRecordset)

CDetailSet::CDetailSet(CCPDatabase* pDatabase)
      : CRecordset(pDatabase)
{
      //{{AFX_FIELD_INIT(CDetailSet)
      m_Item = _T("");
      m_Seq = 0;
      m_Description = _T("");
      m_FeatureCode = _T("");
      m_RecordType = _T("");
      m_ORDERNO = _T("");
      m_nFields = 6;
      //}}AFX_FIELD_INIT
      m_nDefaultType = dynaset;

}


CString CDetailSet::GetDefaultConnect()
{
      return _T("ODBC;DSN=OraTest;UID=user10;PWD=password1");
}

CString CDetailSet::GetDefaultSQL()
{
      return _T("[SC_FRAMES].[SC_FRMSCH_DETAIL]");
}

void CDetailSet::DoFieldExchange(CFieldExchange* pFX)
{
  ......
}

/////////////////////////////////////////////////////////////////////////////
// CDetailSet diagnostics

#ifdef _DEBUG
void CDetailSet::AssertValid() const
{
      CRecordset::AssertValid();
}

void CDetailSet::Dump(CDumpContext& dc) const
{
      CRecordset::Dump(dc);
}
#endif //_DEBUG
-------------------------------------------------------------------------------------------------------
------------------------------Recordset.h
#if !defined(AFX_DETAILSET_H__AD149183_516C_11D2_8176_0060979C789B__INCLUDED_)
#define AFX_DETAILSET_H__AD149183_516C_11D2_8176_0060979C789B__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// DetailSet.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CDetailSet recordset

class CDetailSet : public CRecordset
{
public:
      CDetailSet(CCPDatabase* pDatabase = &((CFrameSchedApp *)AfxGetApp())->m_shPDB);
      DECLARE_DYNAMIC(CDetailSet)

// Field/Param Data
      //{{AFX_FIELD(CDetailSet, CRecordset)
      ...........
      //}}AFX_FIELD


// Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CDetailSet)
      public:
      virtual CString GetDefaultConnect();    // Default connection string
      virtual CString GetDefaultSQL();    // Default SQL for Recordset
      virtual void DoFieldExchange(CFieldExchange* pFX);  // RFX support
      //}}AFX_VIRTUAL

// Implementation
#ifdef _DEBUG
      virtual void AssertValid() const;
      virtual void Dump(CDumpContext& dc) const;
#endif
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DETAILSET_H__AD149183_516C_11D2_8176_0060979C789B__INCLUDED_)
----------------------------------------------------------------------------------------------------------------------------
0
Comment
Question by:Kasinadh
  • 3
  • 3
8 Comments
 
LVL 4

Expert Comment

by:bkfirebird
ID: 10816805
1. Depends .... if you want to use MFC only, you should go ahead with what you are doing .... looks like you have already done all the steps. just create a CDetailSet object and run your queries.
2. you can also do connection pooling with just ODBC
look here for an example on how to establish conn ..... http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmdac/html/pooling2.asp
look here for example to query data .... http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcdirect_execution.asp

HTH
0
 

Author Comment

by:Kasinadh
ID: 10817993
Going with step 1, I am facing a problem.
I'm unable to finish the code to perform connection pooling.
I'm unable to send the handle to my CRecordset.
Its still going through CDatabase for the OpenEx function. My overriding class-function is not being called.

1) Does my Code still look complete? Is it right according to the steps defined.
0
 
LVL 4

Expert Comment

by:bkfirebird
ID: 10818506
>>I'm unable to send the handle to my CRecordset.
you are doing that here .... CDetailSet(CCPDatabase* pDatabase = &((CFrameSchedApp *)AfxGetApp())->m_shPDB);

looks good ...
create a instance of CDetailSet, by default it will take the handle of the m_shPDB object
then start using this CDetailSet object to do queries
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

Author Comment

by:Kasinadh
ID: 10825814
I see that the application is up and running with the changes.
Thank You for all the help here.
Just how would I check the functioning of this program(Connection pooling aspect).( developer privileges only)
0
 
LVL 4

Accepted Solution

by:
bkfirebird earned 500 total points
ID: 10825944
check out the part on how to monitor connection pooling
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmdac/html/pooling2.asp

if your database has a monitoring utility or analyzer, you could use that to see how many connections are being made
0
 

Author Comment

by:Kasinadh
ID: 10847215
Thank You for all the help. I could get to pool the connections. This task is complete.

The reason to accomplish this was to improve performance.
But, I have not noticed any performance improvement. My inserts/updates didnt get any better.
My last question on this would be what factors could I play to take advantage of pooling.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now