Click here to Skip to main content
15,881,089 members
Articles / Desktop Programming / MFC

ADO MFC Wrapper classes

Rate me:
Please Sign up or sign in to vote.
4.17/5 (11 votes)
11 Aug 20023 min read 149.3K   10.3K   65   17
ADO classes that closely resemble CDatabase and CRecordset.

Introduction

For an assignment at work, I needed to create a set of classes that would use ADO to read from a database. After using tons of code from Code Project over the last few months, I decided I would try to give something back.

The benefits of using ADO/OLE DB versus ODBC are:

  1. speed improvements,
  2. provider flexibility (if you create a custom OLE DB provider, you can use these classes for your consumer),
  3. industry standard for database access, ...

If you're going to be using VB, there is no reason to not use ADO almost always because of the way VB provides a very user friendly interface to ADO.

There is not a user friendly interface available for ADO with Visual C++. There are code examples on MSDN and other sites (for instance Bob Place's article on CodeGuru), but there is no support built into MFC. Anyone who is familiar with MFC and the class wizard, certainly appreciates the help given when using ODBC for static binding. Static binding is a quicker means of reading the database when you will be reading/updating several rows from a table. For my purposes, this efficiency was very essential. These classes and the wizard make doing this a breeze.

The interface presented with CDatabase, CRecordset and CDBVariant is very sufficient to perform dynamic binding and is standard MFC. I wanted an interface for using ADO that was basically equivalent to this.

Like all programmers who enjoy code reuse, the first step for creating this interface was seeing what was already available. I found two articles here on CodeProject that provided very nearly exactly what I was after. They are the ADO classes by Carlos Antollini and the ADO Data Bound class wizard by Ly Nguyen.

Basically, my work involved integrating these and providing an interface as similar to CRecordset and CDatabase as possible.

The classes provide all the functionality for dynamic binding (while also converting to MFC types from VARIANT types) and a very simple interface for static binding.

All the details and exceptions involving ADO and COM are encapsulated.

Here is a very simple example of using the classes with dynamic binding:

C++
// use the jet to read, we know the layout each
// record so we call the getfieldvalues w/
// the pre-known datatypes for the columns.
//       CADODatabase db;
//
//       BOOL bOpen = db.Open("s:\\tim\\climet.mdb", "Admin", 
//                               "", "Microsoft.Jet.OLEDB.3.51");
//       CADORecordset rs(&db);   
//
//       BOOL bRsOpen = rs.Open("select * from client_dim");
//
//       int nRows = rs.GetRecordCount();
//
//       int nKey;
//       CString strCliNm, strCliDesc;
//
//       BOOL fok = TRUE;
//
//       fok = rs.GetFieldValue(0, nKey);
//       fok = rs.GetFieldValue(1, strCliNm);
//       fok = rs.GetFieldValue(2, strCliDesc);
//   
//       db.Close();

Here is a very simple example of using the classes with static binding:

First, we use the included wizard (Ly Nguyen's application slightly modified) to generate the class that derives from both CADORecordBinding and from CADORecordset:

Image 1

In later steps, the wizard allows you to specify a table and the wizard generates the binding macro calls (ADO_FIXED_LENGTH_ENTRY, etc) for you. Of course, you'll have to add the header to your project file and add the path to the .dll's headers in your project settings:

Image 2

First the CADORecordset derived class (the wizard's output):

C++
/////////////////////////////////////////////////////////////////////////////
// CClientPlanRS class

class CClientPlanRS : public CADORecordBinding, public CADORecordset
{
BEGIN_ADO_BINDING(CClientPlanRS)
    ADO_FIXED_LENGTH_ENTRY    (  1, 
       adInteger, m_lClient_Key, m_ulClient_KeyStatus, TRUE)
    ADO_VARIABLE_LENGTH_ENTRY2(  2, 
       adVarWChar, m_szClient_Name, sizeof(m_szClient_Name), 
       m_ulClient_NameStatus, TRUE)
    ADO_VARIABLE_LENGTH_ENTRY2(  3, 
       adVarWChar, m_szClient_Description, 
       sizeof(m_szClient_Description), 
       m_ulClient_DescriptionStatus, TRUE)
END_ADO_BINDING()

//Attributes
public:
    LONG    m_lClient_Key;
    ULONG   m_ulClient_KeyStatus;
    CHAR    m_szClient_Name[51];
    ULONG   m_ulClient_NameStatus;
    CHAR    m_szClient_Description[256];
    ULONG   m_ulClient_DescriptionStatus;
    CClientPlanRS(CADODatabase* pDb, int nCacheSize = -1) :  
            CADORecordBinding(),                        
            CADORecordset(pDb, nCacheSize)              
            { SetRecordBinding(this); } 

}; 

And now using it. We'll use the Microsoft OLE DB provider for ODBC, so we don't have to specify the provider parameter. Also we will connect using an ODBC DSN.

C++
//       bOpen = db.Open("CLIMET", "TDK2", "NOONHIGH");
//
//       CClientPlanRS CliRs(&db);
//
//
//       //read table:
//       bRsOpen = CliRs.Open("select * from client_dim");
//   
//       while (!CliRs.IsEOF())
//       {
//         //do something w/ the records
//         CliRs.MoveNext();
//       }
//
//       //update the first existing row:
//       CliRs.MoveFirst();
//
//       strcpy(CliRs.m_szClient_id_name, "MAYO999");      
//       BOOL bUpdate = CliRs.Update();
//
//       //add a new row:
//       CliRs.m_lClient_id = 999;
//       strcpy(CliRs.m_szClient_id_name, "PICKLE");      
//       strcpy(CliRs.m_szClient_id_desc, "Pickle Inc");
//       BOOL bAdd = CliRs.AddNew();
//

It is important to note that these classes do not throw exceptions. Rather their methods return BOOLs.

The code itself is heavily commented so please review it for further details.

History

  • 12th August, 2002: Initial version

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.


Written By
Chief Technology Officer
United States United States
Working to keep a technology company up to date. Wondering when Microsoft will hire a fresh, innovative guy to run the company.

Comments and Discussions

 
QuestionThe License of This code Pin
Member 1525076421-Jun-22 14:34
Member 1525076421-Jun-22 14:34 
QuestionCompile error problems in VC2010 Pin
maplewang13-Jul-12 21:54
maplewang13-Jul-12 21:54 
SuggestionSetFieldEmpty Pin
yeajay18-Apr-12 3:13
yeajay18-Apr-12 3:13 
QuestionLicense information [modified] Pin
+=manuel=+14-Jul-11 2:26
+=manuel=+14-Jul-11 2:26 
GeneralRecordsets Pin
Graham Reeds30-Jun-06 3:33
Graham Reeds30-Jun-06 3:33 
GeneralConnectionString Pin
Graham Reeds29-Jun-06 21:58
Graham Reeds29-Jun-06 21:58 
GeneralIt does not work Pin
StjepanVukadin25-Feb-06 0:43
StjepanVukadin25-Feb-06 0:43 
GeneralPls Help me make function (save/load) fields images from SQL Server Pin
An Phung Nguyen11-Nov-05 21:55
An Phung Nguyen11-Nov-05 21:55 
Generalno appropriate default constructor available when trying to create and instance, & unhandle exception Pin
Member 227165527-Sep-05 19:26
Member 227165527-Sep-05 19:26 
GeneralUnhandled Exception !!!!! Pin
Furno Gianluca4-Feb-05 6:10
Furno Gianluca4-Feb-05 6:10 
AnswerRe: Unhandled Exception !!!!! Pin
bewster19-Jan-06 2:45
bewster19-Jan-06 2:45 
QuestionHow can I use addnew on empty database table Pin
rosario0120-Jan-05 10:40
rosario0120-Jan-05 10:40 
Why if I use Addnew on a table with zero records I get an error ?
GeneralProblems with win98 Pin
mytechiedata2-Mar-04 17:07
mytechiedata2-Mar-04 17:07 
GeneralCADOTestApp fails Pin
Member 40379423-Jul-03 6:12
Member 40379423-Jul-03 6:12 
GeneralSeek Pin
Aleksandar Radulovic14-May-03 6:03
Aleksandar Radulovic14-May-03 6:03 
GeneralWow - Thanks Pin
Peter Tewkesbury21-Aug-02 22:54
professionalPeter Tewkesbury21-Aug-02 22:54 
QuestionHow can I get access to m_pDatabase from a _RecordsetPtr Pin
Fantasia Banzai16-Aug-02 19:02
sussFantasia Banzai16-Aug-02 19:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.