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.
- Add all of the files included in
AxLib
to your project. That is: AxLib.h, AxConnection.cpp, AxCommand.cpp, AxRecordset.cpp and AxException.cpp. - Create derived version(s) of
CAxCommand
(if stored procedures are involved) and implement the virtual methods _CreateParameters
and _UpdateParameters
. - Create derived version(s) of
CAxRecordset
and implement the virtual methods _SetDefaultValues
and DoFieldExchange
. - 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:
#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;
void _SetDefaultValues()
{
m_szAccountID = _T("");
m_szName = _T("");
m_szAddress = _T("");
m_szPhone1 = _T("");
m_szPhone2 = _T("");
m_szEmail = _T("");
m_szNote = _T("");
};
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