Click here to Skip to main content
15,886,806 members
Articles / Desktop Programming / Win32

dbAx: a C++ Library for ActiveX Data Objects (ADO)

Rate me:
Please Sign up or sign in to vote.
4.93/5 (24 votes)
21 Jan 2009CPOL4 min read 103.8K   2.4K   98   40
C++ class wrapper for ADO

Screenshot - dbAx.jpg

Introduction

I have long worked with database design and implementation, primarily with Microsoft SQL Server. I am also a die-hard C++ fan. The old school gave us Data Access Objects (DAO), which provided a fairly good interface for C++ users. Then ActiveX Data Objects (ADO) came along. Great environment, but not a lot of support for the C++ crowd. I began to feel like the red-headed orphan stepchild.

As I said, I live, eat and sleep C++. I am also passionate about document management (another subject altogether) and interfacing with many other applications and libraries, most of which involve getting to a database of some sort. I know, I know. There’s VB: don’t want to go there. There’s also .NET: haven’t got (all the way) there yet!

To get to the point: this inspired me to work on my own set of classes that would make database-ing not so painful for the C’er in all of us. Rather than coming up with some other variation involving an "A" and a "D" and an "O," I chose the name dbAx.

Background

Actually, dbAx is a library composed of C++ classes collectively called AxLib and a small utility program called AxGen. AxLib contains classes for connecting to a data source and command, as well as recordset classes for dealing with the actual data tables. The AxGen utility allows you to easily create custom versions of the command and recordset classes for the task at hand.

Some of the benefits to using dbAx are freedom from dealing with COM interfaces and pointers, easily implementing parameterized queries (stored procedures) and avoiding the manipulation of variant data types. The library automatically handles the translation to and from native C++ class data members.

Before continuing, it should be noted that included in the available download is a Windows compiled help file that covers all aspects of dbAx. I will only mention the main points here. Also, there is a sample application called CardFile that demonstrates many of the features of the dbAx library.

Using the Code

AxLib defines six classes, several of which have virtual methods and are intended to act as a base class for an application-specific version. The primary classes are: CAxConnection, CAxCommand and CAxRecordset. As you may have guessed, these support the connection to, and accessing of, database information.

In support of these main classes are CAxException, CAxConnectionEvents and CAxRecordsetEvents. The CAxException class provides for exception handling while the CAxConnectionEvents and CAxRecordsetEvents classes enable the handling of events that may be raised by the data provider.

The following is a quick outline of how to get started. Again, the included help file goes into much more detail.

  1. Add all of the files included in AxLib to your project. That is: AxLib.h, AxConnection.cpp, AxCommand.cpp, AxRecordset.cpp and AxException.cpp.
  2. Create derived version(s) of CAxCommand (if stored procedures are involved) and implement the virtual methods _CreateParameters and _UpdateParameters.
  3. Create derived version(s) of CAxRecordset and implement the virtual methods _SetDefaultValues and DoFieldExchange.
  4. Create instances (member variables) of CAxConnection and of the derived versions of CAxCommand and CAxRecordset.

In your application, generally the main procedure will:

  • Call the dbAx::Init() method to initialize the library.
  • Set up a connection string that will be used with the CAxConnection object.
  • Set up and initialize each of the CAxCommand objects, if any.
  • Open the CAxRecordset objects, either directly or by way of an associated CAxCommand object.
  • At program termination, call the dbAx::Term() method.

AxGen

As noted, the CAxCommand and CAxRecordset classes define virtual methods that are generally overridden and include calls to other class methods for creating and updating parameters, as well as exchanging the field data of a recordset. This involves mapping the database fields to member variables and indicating the correct SQL data type. This can become quite tedious and error-prone, especially in the case of tables with a large number of data fields.

AxGen is a utility that attempts to connect to a target data provider and read the schema of stored procedures and data tables. You can then specify a name and quickly generate the source code for a custom derived class. This can be a big time-saver, especially during development when the database structure may be in a state of constant change. AxGen also implements Microsoft’s connection wizard, where you can build the required connection string for a specific data provider. A sample CAxRecordset class created by AxGen follows:

C++
/**************************************************************************
    File: AxAccountSet.hpp
    Date: 11/22/2007
      By: Data Management Systems (www.dmsic.com)

    DESCRIPTION
    The following source code was generated using the AxGen utility and is
    intended to be used in conjunction with the dbAx library. This class
    facilitates the exchange of data with the ADO data source from which
    it was derived.

    Table: (local)\CardFile\ACCOUNT

    Include this file in your project.

    DISCLAIMER
    This source code is provided AS-IS with no warranty as to its
    suitability or usefulness in any application in which it may be used.
**************************************************************************/

#pragma once
#include <AxLib.h>

using namespace dbAx;

class CAxAccountSet :
    public CAxRecordset
{
public:
  CAxAccountSet() { _SetDefaultValues(); }
  ~CAxAccountSet() { }

  CString     m_szAccountID;
  CString     m_szName;
  CString     m_szAddress;
  CString     m_szPhone1;
  CString     m_szPhone2;
  CString     m_szEmail;
  CString     m_szNote;

  //Set default values of class members
  void _SetDefaultValues()
  {
    m_szAccountID  = _T("");
    m_szName       = _T("");
    m_szAddress    = _T("");
    m_szPhone1     = _T("");
    m_szPhone2     = _T("");
    m_szEmail      = _T("");
    m_szNote       = _T("");
  };

  //Exchange field values with data provider
  void DoFieldExchange(bool bSave = FALSE)
  {
    FX_VarChar           (bSave, _T("AccountID"),  m_szAccountID);
    FX_VarChar           (bSave, _T("Name"),       m_szName);
    FX_Text              (bSave, _T("Address"),    m_szAddress);
    FX_VarChar           (bSave, _T("Phone1"),     m_szPhone1);
    FX_VarChar           (bSave, _T("Phone2"),     m_szPhone2);
    FX_VarChar           (bSave, _T("Email"),      m_szEmail);
    FX_Text              (bSave, _T("Note"),       m_szNote);
  };
};

Conclusion

Developing the library has given me better insight into ADO, COM and programming in general. I can say that an honest attempt has been made to produce a workable and bug-free library, but my work/test environment is limited and there is always the one that gets through. Certainly any feedback on errors and usability is welcome. I hope dbAx proves itself useful to all who decide to try it.

History

  • 21/12/07 v1.0 Initial release
  • 25/01/08 Corrected errors in the AxGen module resulting in bad source code being generated
  • 05/03/08 v1.10 Numerous updates, code fixes, code generation and more; see AxLib.h Revision History for details
  • 01/20/09 v1.2 Bug fixes and code update. See AxLib.h for details

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Unknown
I work almost exclusively with C++ and database applications and manage the IT concerns for the engineering department of a large food processing company. As such, I get involved with add-ons to existing commercial software, SCADA, interfacing with industrial components (PLC’s, automated weight checking machines, etc.) and other pet projects (currently working on v4.0 of my own document management app).

I get totally fed-up, frustrated and thoroughly delighted with programming and computers, but always remember the sage words of an old lab tech from my Air Force days; “There was never a statue erected to the man who left well enough alone.” I’ll be at it again tomorrow!

Comments and Discussions

 
Questiongreate lib but rely on CString and oledatetime? Pin
maplewang26-Aug-08 14:41
maplewang26-Aug-08 14:41 
AnswerRe: greate lib but rely on CString and oledatetime? Pin
Ross White27-Aug-08 9:30
Ross White27-Aug-08 9:30 
AnswerRe: greate lib but rely on CString and oledatetime? Pin
Rolf Kristensen25-Jun-10 13:15
Rolf Kristensen25-Jun-10 13:15 
GeneralFYI - Clean Compile and Link using VS2K8 32 & 64 bit XP & Vista Pin
1000mp17-May-08 3:46
1000mp17-May-08 3:46 
GeneralRe: FYI - Clean Compile and Link using VS2K8 32 & 64 bit XP & Vista Pin
Ross White20-May-08 4:13
Ross White20-May-08 4:13 
QuestionWhat suitable databound GUI controls do you recommend for Win32 C++ OLE DB/ADO database applications? Pin
Alexandru Matei18-Mar-08 4:08
Alexandru Matei18-Mar-08 4:08 
AnswerRe: What suitable databound GUI controls do you recommend for Win32 C++ OLE DB/ADO database applications? Pin
Ross White18-Mar-08 8:02
Ross White18-Mar-08 8:02 
QuestionDatabase related files are missing. Pin
Garudappa6-Mar-08 16:59
Garudappa6-Mar-08 16:59 
We are able to compile the program, but the program cannot reference some of the sybase related definitions( which are available in ctlib and cslib of sybase source files mentioned below), due to this we are getting the below linker errors.



Do we need to use the different ct/cs libraries for Windows to connect into the sybase running on Solaris system?

Is the source/libraries are available to download for Windows?



Could somebody give some inputs on this.



ctcancel.c

ctcmd.c

ctresult.c

ctrinfo.c

ctdesc.c

ctbind.c

ctfetch.c

csconfig.c

ctcallbk.c

ctinit.c

ctexit.c

csctxdrp.c

csctxglb.c

ctcon.c

cscnvrt.c





Linker Errors are below:

Error 278 error LNK2019: unresolved external symbol _ct_con_props@24 referenced in function _DB_AddCmd coDbGen_ct.obj

Error 279 error LNK2019: unresolved external symbol _ct_cmd_drop@4 referenced in function _DB_SubmitQuery coDbGen_ct.obj

Error 280 error LNK2019: unresolved external symbol _ct_cancel@12 referenced in function _DB_SubmitQuery coDbGen_ct.obj

Error 281 error LNK2019: unresolved external symbol _ct_send@4 referenced in function _submitQuery coDbGen_ct.obj

Error 283 error LNK2019: unresolved external symbol _ct_command@20 referenced in function _submitQuery coDbGen_ct.obj

Error 284 error LNK2019: unresolved external symbol _ct_cmd_alloc@8 referenced in function _submitQuery coDbGen_ct.obj

Error 286 error LNK2019: unresolved external symbol _ct_results@8 referenced in function _getResults coDbGen_ct.obj

Error 287 error LNK2019: unresolved external symbol _ct_res_info@20 referenced in function _getNumRows coDbGen_ct.obj

Error 288 error LNK2019: unresolved external symbol _ct_fetch@20 referenced in function _getRowResults coDbGen_ct.obj

Error 289 error LNK2019: unresolved external symbol _ct_bind@24 referenced in function _getRowResults coDbGen_ct.obj

Error 290 error LNK2019: unresolved external symbol _ct_describe@12 referenced in function _getRowResults coDbGen_ct.obj

Error 291 error LNK2019: unresolved external symbol _cs_config@24 referenced in function _coDbInit coDbGen_ct.obj

Error 292 error LNK2019: unresolved external symbol _ct_callback@20 referenced in function _coDbInit coDbGen_ct.obj

Error 293 error LNK2019: unresolved external symbol _ct_init@8 referenced in function _coDbInit coDbGen_ct.obj

Error 294 error LNK2019: unresolved external symbol _cs_ctx_drop@4 referenced in function _exitHandler coDbGen_ct.obj

Error 295 error LNK2019: unresolved external symbol _ct_exit@8 referenced in function _exitHandler coDbGen_ct.obj

Error 296 error LNK2019: unresolved external symbol _cs_ctx_global@8 referenced in function _exitHandler coDbGen_ct.obj

Error 297 error LNK2001: unresolved external symbol _cs_ctx_global@8 DBCmn_ct.obj

Error 302 error LNK2019: unresolved external symbol _ct_connect@12 referenced in function _coDbConnect_P coDbGen_ct.obj

Error 305 error LNK2019: unresolved external symbol _ct_con_drop@4 referenced in function _coDbConnect_P coDbGen_ct.obj

Error 306 error LNK2019: unresolved external symbol _ct_con_alloc@8 referenced in function _coDbConnect_P coDbGen_ct.obj

Error 307 error LNK2019: unresolved external symbol _cs_ctx_alloc@8 referenced in function _coDbConnect_P coDbGen_ct.obj

Error 308 error LNK2019: unresolved external symbol _ct_close@8 referenced in function _coDbDisconnect coDbGen_ct.obj

Error 311 error LNK2019: unresolved external symbol _cs_convert@24 referenced in function _coDbConvert DBCmn_ct.obj
GeneralRe: Database related files are missing. Pin
Ross White7-Mar-08 4:38
Ross White7-Mar-08 4:38 
GeneralError in FX_Integer(bool bSave, LPCTSTR lpszColumn, int& value) Pin
RoMuc2-Feb-08 18:32
RoMuc2-Feb-08 18:32 
GeneralRe: Error in FX_Integer(bool bSave, LPCTSTR lpszColumn, int& value) Pin
Ross White3-Feb-08 16:30
Ross White3-Feb-08 16:30 
QuestionImage other than BMP Pin
Patrickquinn121230-Jan-08 4:24
Patrickquinn121230-Jan-08 4:24 
GeneralRe: Image other than BMP Pin
Ross White30-Jan-08 5:47
Ross White30-Jan-08 5:47 
AnswerRe: Image other than BMP Pin
Jim Crafton21-Jan-09 10:59
Jim Crafton21-Jan-09 10:59 
QuestionWhy the CAxRecordset::Open function does'nt call my own DoFieldExchange(FALSE) function? Pin
Jason.Han24-Jan-08 1:35
Jason.Han24-Jan-08 1:35 
AnswerRe: Why the CAxRecordset::Open function does'nt call my own DoFieldExchange(FALSE) function? Pin
Jason.Han24-Jan-08 15:18
Jason.Han24-Jan-08 15:18 
AnswerRe: Why the CAxRecordset::Open function does'nt call my own DoFieldExchange(FALSE) function? Pin
Ross White24-Jan-08 17:27
Ross White24-Jan-08 17:27 
GeneralAXGen Pin
RoMuc30-Dec-07 1:21
RoMuc30-Dec-07 1:21 
GeneralRe: AXGen Pin
Ross White30-Dec-07 14:45
Ross White30-Dec-07 14:45 

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.