Here's how to provide an object-oriented solution using the MFC database classes, Data objects, and Meta classes.
As an object programmer, there are times when using the MFC database classes directly or deriving classes &om them is handy. The MFC database classes provide a quick route to delivering a database application to users with minimal code on your behalf. You should be familiar with ODBC, Visual C++, and MFC (for the first part of the article), and Visual Basic (for the second part of the article). A basic understanding of OLE will also be helpful.
The MFC classes still leave the developer with the onus of tracking internal database changes that can affect hard-coded data access functions. In this article, my first intent is to describe the inherited problem of database access (retrieving records and managing data), and then find a solution for it. Since there's a lot of information to cover, this article is the first in a two-part series in which I discuss the server code to handle creation of a Data object, Meta classes, and so on. built the server code using Visual C++ and MFC. The second part describes the process of building an application to communicate with the server code in Visual Basic. You will find the code on this issue's COMPANION RESOURCE DISK.
The inherited problem
When you write a database aware application, you must understand both sides of the clientserver architecture. On the client side, you need to deal with user interface components and controls such as windows and window controls. But as the industry's emphasis has turned to client-server development, even front-end programmers have begun to learn more about the back-end of client-server projects.
You need to determine which databases, tables, and fields (or rows) you'll gather information from, and furthermore, how to manage the data. In the past, database management came almost exclusively in the form of a Structured Query Language (SQL). Even ODBC has a form of SQL. You implement this form by using certain API functions, or by passing strings to one or two functions. The strings contain a SQL statement, which is then passed to the appropriate driver.
There are two popular formats for calling SQL from your applications. The first is to send a string to a function (similar to what I just described). The second method is to place embedded SQL statements in your code and run an interpreter against your code files. The interpreter in turn, creates files which make API calls with strings as parameters, similar to the first method.
Class libraries take a different approach to using SQL and database management. Most of the time, you're provided with several classes and/or functions to derive from and override, respectively. By providing the appropriate data in your derived classes, you end up telling the class library of your intent to use a particular database, table, and field. The class library does the rest. It provides a connection to the database, for the opening of tables, and for the loading of data from the tables.
Continuing with our inherited problem, what happens if the database administrator in your company changes or adds one or two fields in the database? You have to modify your code to match the new structure of the database.
In figure 1, I have a grid control that contains data gathered from a database. Furthermore, this data came from several different tables. Optimally, I could use a join to gather the data, place the data into a recordset, traverse through the recordset, and pull out the information I want.
Since this data-fetching method is hard-coded into my application, anytime that something changes on the database side, I have to be aware of the changes and be prepared to change my code. This means that even if the change is minor (renaming a column or changing a column's type), I still might have to change something in my code, test it, compile and link for release mode, and release the product.
The solution to this problem lies in determining what data to retrieve from the database based on information stored in the database. In other words, if you query the database to determine what a given object should look like, the database can tell you where and how to retrieve the data in order to reconstruct the object. This Js called a Business Object Model (BOM).
A BOM lets you determine at runtime what an object will look like. Once this information is known, you can go after the data to fill the object. Each object always contains two parts: its class (or type) information and its actual data. The class information determines the fields of the object. This for example, tells the object, you have a field for the customer's name or you have a field for the customer's address. The data is the actual name such as "Jane Doe" or the actual address such as "99 Munster Blvd".
During the next few sections, I'll explain exactly what a BOM is and describe the necessary steps to build and implement your own object models for use in your applications.
Object model basics
An object model lets you build applications faster with less maintenance. The model provides objects (on request), that contain the data fields needed by a calling application. End users of an application (built using the model) can more easily create and manage business data stored in a database.
The model contains all the business rules for proper data entry, browsing, and calculations that should be applied to the business objects. Customers, orders, and detail objects are some examples of objects commonly created via the object model. In actuality, the model only knows where on the database to find the necessary information to build an object. The calling application supplies an identifier for the object's class, and the object model finds and …