C++ with Relational Databases
Oracle Database Tips by Donald Burleson
With the increasing popularity of
object-oriented technology, many relational database shops want the
ability to take advantage of C++ applications while continuing to use
their relational databases. The widespread acceptance of object
technology has lead many companies to the conclusion that they must
embrace object-orientation, but they remain skeptical about the maturity
of the object-oriented database (OODB) technology. Many companies are
averse to risk and do not want to embrace one of the nascent OODB
offerings, and they cannot wait for the object/relational databases.
Other companies who have invested millions of dollars in relational
database systems want to continue with a relational architecture without
missing out on the benefits of object technology.
When interfacing object-oriented languages with
relational databases there is a problem encountered when using SQL with a
general-purpose object-oriented programming language, in which an "Impedance
mismatch" is created.
There are two aspects to this impedance mismatch
between SQL and objects:
Difference in programming paradigms, for
example, between a declarative language such as SQL and an imperative language
such as C++.
A mismatch in the type systems, causing a
loss of information to occur at the interface. The DML, in most relational
database systems does not support the computational completeness to
express complex mathematical manipulations of data common to engineering
design. However OODBMS's, provide database extensions to computationally
complete programming languages, like C++ and Smalltalk, that are capable of
handling complex mathematical manipulations typical of large-scale programs
that are common to engineering design.
Regardless of the promises of the relational
database vendors, there are those who wish to enjoy the benefits of a robust and
mature database while continuing to pursue object technology. However, there
are drastic differences between object technology and relational databases. In
a true OODB, object persistence (storing the object) is achieved by calling a
method for the object that makes the object reside in permanent disk storage.
In other words, persistence is just another method that is associated with the
object. This is very different from a relational database where a row can be
inserted from any program at any time.
Unlike relational databases, the OODB offerings
also have a very tight coupling of the database with the host programming
language. Consequently OODB's generally are designed with a specific language
in mind, such as C++ or SmallTalk. Relational databases such as Oracle are
language independent, and many Oracle shops are having success writing C++
applications and running them through the Pro*C precompiler.
There are many different approaches to using a
relational database with an object-oriented application, and this text offers
only one of many different approaches. However, all of the approaches involve
some common factors and procedures. The goal of "stuffing" an object into a
relational table generally involves the following steps:
Document the object structure
for the application.
diagrams, Rumbaugh diagrams, etc.)
Review all methods with the
Review the object navigation
and create logical pointers.
Add object extensions to
manage internal pointers.
For each class, map the data
items and pointers to a relational table.
Write C/SQL snippets to move
the object data and pointers into the table row.
Re-write the I/O to utilize
the logical pointers.
While these steps are not exhaustive, they
describe the major steps in converting a C++ application to function with a
relational database. While these are the steps, it must be stressed that every
application is different. A C++ application that uses logical pointers, avoids
"arrays of pointers" and isolates object I/O is very easy to back-end into a
relational database. On the other hand, a C++ application that uses physical
object address as pointers (i.e. capturing the address of an object and
embedding it in another object to establish a relationship), utilizes arrays of
pointers, and has separate I/O statements within each method can be very
difficult to back-end to a relational database.
This chapter will illustrate some of these
issues and provide examples on how to write C++ code that can utilize relational
engines for persistent object storage.