The internal storage layer and class RWDBValue can be entirely invisible to your application if you want them to be. As noted earlier, it is easy to write DBTools.h++ applications that use only the native C++ types, and the few concrete classes for storage of structured data. Nevertheless, we have included RWDBValue in the public class hierarchy for three reasons:
Some applications need to store data without knowing its type. RWDBValue provides a convenient mechanism for doing this.
Some applications may want to store tabular data as a collection. Since heterogeneous collections present special problems, we have attempted to make this task easier. Class RWDBValue derives from RWCollectable, so instances can be stored in any of the Tools.h++ Smalltalk-like collection classes.
Some applications may need an easy way to store entire database tables in program memory. Class RWDBMemTable accomplishes this, using RWDBValue as the datatype of its cells.
Your applications may not need to use RWDBValue; if they don't, you can skip most of this chapter. However, we do recommend that you review the material about RWDBValue::ValueType and rwdbNull, since these components are used elsewhere in the DBTools.h++ API.
Class RWDBValue is the DBTools.h++ means of achieving normalization of datatypes. Class RWDBValue converts database-dependent types to C++ types, and vice-versa. It provides storage for any native C++ type and for any of the structured types used by DBTools.h++. It also adds NULL/not NULL semantics to the primitive types.
NOTE: Unlike most DBTools.h++ classes, RWDBValue obeys value semantics.
Class RWDBValue offers a compromise between type safety, functionality, and efficiency. For example, although this class is relatively efficient in both time and space, we do not sacrifice type safety entirely; for example, we reject the notion of storing only a pointer and a length. Also, RWDBValue supports the concept of early binding of data discussed earlier.
You will find a complete entry for RWDBValue in the DBTools.h++ Class Reference, but its main components are listed here:
An enumerated type, ValueType, which codes the datatype of the stored value. The possible ValueTypes are Char, UnsignedChar, Int, UnsignedInt, Short, UnsignedShort, Long, UnsignedLong, Float, Double, String, Blob, Date, DateTime, Duration, and Decimal. To avoid polluting the global name space, all our enums are scoped within classes. To refer to a member of the enumeration outside the scope of RWDBValue, use the scoping operator ::, as in RWDBValue::String, for example.
A friend, rwdbNull, which is of type RWDBValueManip, and represents a literal NULL value. There is a constructor and an assignment operator that allow RWDBValue instances to be formed from rwdbNulls and other RWDBValueManips.
A C++ union that can store a long, unsigned long, double, RWCString*, RWDecimalPortable*, RWDBDateTime*, RWDBDuration*, or RWDBBlob*. (The asterisk indicates a pointer to that type.)
Member functions type()and isNull()to access the value's datatype and NULL attribute, respectively.
Constructors and assignment operators that allow an RWDBValue to be constructed or copied from any C++ primitive or from any DBTools.h++ structured type.
The member function canConvert(ValueType), which detects whether or not a given value can be converted to a specified type.
A collection of conversion routines such as asInt(), asDouble(), asString(), and so on, which convert a given value to the type implied by the routine name.
Member functions isEqual(), compareTo(), binaryStoreSize(), saveGuts(), and restoreGuts(), which are required to make RWDBValue persistable, as defined by Tools.h++. (RWDBValue is derived from RWCollectable.)
Whenever data arrives from a database, routines in the database layer interrogate the database API for its type, and store the data as the best suited ValueType. For most types, this is simply a matter of copying some bytes, but for types that arrive in a database-dependent format, like date or money, type conversion is done on the spot.
Whenever the application layer requests data from the internal storage layer, the canConvert() routine is consulted to determine whether or not the conversion can be made. If not, an error condition arises. Otherwise, the appropriate asType()routine is invoked to convert to the requested type.
©Copyright 2000, Rogue Wave Software, Inc.
Contact Rogue Wave about documentation or support issues.