Using the dbDAO Classes

The intent of the dbDAO classes is to make the resulting DAO C++ code as similar to equivalent Microsoft Visual Basic code as possible. Fundamental DAO concepts such as properties, methods, and collections are supported by the dbDAO classes.

The following procedure, taken from the Employee example in the DAO SDK, illustrates how to call dbDAO from your application. This procedure displays a dialog box (using Microsoft Foundation Classes (MFC)) that prompts for the location of the Northwind database. After the user enters the location of Nwind.mdb, a recordset based on the Employees table is opened. If the Employees table cannot be opened, an error is displayed. (The dbDAO code is nested in a try-catch block.)

BOOL CDAOEMP2Doc::ConnectToDatabase()
{
   CFileDialog   cOpenFile(
            TRUE, 
            _T("MDB"), 
            _T("employee.mdb"), 
            OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, 
            (_T("Access Files (*.mdb) |*.mdb ||")));

   /* Get the location of database (assume it's the
      Employee example) */
   cOpenFile.DoModal();

   /* The following was declared in class CDAOEMP2Doc:
   CdbDBEngine    m_cDBEngine;
   CdbDatabase      m_cNWDatabase;
   CdbRecordset   m_cEmpRecordSet;
   */
   try
      {
      m_cNWDatabase = m_cDBEngine.OpenDatabase(
            cOpenFile.m_ofn.lpstrFile);
      m_cEmpRecordSet =
         m_cNWDatabase.OpenRecordset(_T("Employees"),
            dbOpenDynaset);
      }

   catch (CdbException e)
      {
      CdbLastOLEError exError;
      TCHAR szBuf[256];

      wsprintf(szBuf, _T("Error 0x%lx : %s\n"),
         e.m_hr, (LPCTSTR) exError.GetDescription());
      AfxMessageBox(szBuf);
      }
   
   return TRUE;
}

Although the actual DAO code in this example amounts to a couple lines, this is a typical dbDAO call. The following sections examine what is going on here in greater detail.

dbDAO Syntax

The table below demonstrates how syntactically similar the above dbDAO code (with lengthy argument names and macro decorations removed) is to Visual Basic.

dbDAO Visual Basic
CdbDBEnginee;

CdbDatabased;

CdbRecordsetr;

d = e.OpenDatabase("nwind.mdb");

r = d.OpenRecordset("Employees");

Dim d as Database

Dim r as Recordset

Set d = OpenDatabase("nwind.mdb")

Set r = d.OpenRecordset("Employees")


One notable difference is that for dbDAO, declaring a variable of class CdbDBEngine must be the first DAO call. This declaration calls the constructor function that creates an instance of the CdbDBEngine object. For more information, see Initializing CdbDBEngine.

Other than language differences — regarding how to type variables, for example — there are some general differences in the way DAO properties, methods, and collections appear in code, as detailed in the following sections.

Properties

Properties in the dbDAO classes are defined differently from the way they are defined in Visual Basic. The PropName type library property, for example, is exposed as two methods: GetPropName and SetPropName. If the property is read-only, then only the Get method is exposed. Likewise, if the property is write-only, then only the Set method is exposed. The Get method takes no arguments and returns the value of the property, using the appropriate C data type where possible. The Set method takes a single argument — the new value to which you want to set the property — again using the appropriate C data type where possible.

For example, the Name property of an object is mapped to the GetName and SetName methods. Therefore, its C prototypes are as follows:

CString      GetName (VOID);
VOID         SetName (LPCTSTR pstr);

Variants

Some properties return data of various types. The most obvious of these are the Value properties of Field objects. These have to return variants because the data type of the return value isn’t known until run time.

Default Properties

Visual Basic has default properties. For example, the code

a = rs!FirstName

is equivalent to

a = rs!FirstName.Value

Here, Value is the default property of the Field object. Because C++ has no equivalent syntax, you have to ask for the default property by name:

a = rs.Fields["FirstName"].GetValue();

For this particular call, note that the performance of this code could be improved by using the dbDAO GetField method.

Methods

Visual Basic methods map directly to methods in the dbDAO classes. Visual Basic methods that take optional arguments may also omit any or all optional arguments in these classes. If you omit an optional argument, a default value is supplied for the argument.

Methods take C types as arguments rather than the more common VARIANT data type used in the OLE classes and VBA. See the individual method prototypes in DBDAO.H for details.

Collections

The dbDAO classes emulate Visual Basic’s collections by providing member variables that point to collections. As with default values, there is no automatic lookup syntax, which means you have to use an explicit Item method. This method is overloaded to allow you to specify either an ordinal or string index in the collection.

Automatic construction and destruction of the these references means that statements like

d.m_Tabledefs.Item(i).Name

are legal and result in the correct allocation of the referenced Item (a TableDef object in this case), and its deallocation when the reference is complete. Of course, for repeated access, it is better to declare an explicit reference, but for one-time use, this is a convenient way to retrieve collection values.

A convenient shorthand for specifying an item in a collection is to use the [ ] operator. The same statement would then be:

d.m_Tabledefs[i].Name

Note If you use reference fields by ordinal, cast the index as LONG to prevent the compiler from interpreting “0” as NULL (as shown in the ConnectToDatabase function in the Employee example).