The Value Layer
The value layer consists of the data and variables you pass by value when writing to the value-based classes of the DB Interface Module. Performance features such as inserter and reader caching make these classes both efficient and easy to use. (See Chapter 9, Caching.) Applications using these classes can move data back and forth safely and efficiently between the value layer and the variables in the application. Typically, this is done with the insertion << and extraction >> operators of the various classes. For example, if you want to insert some integers into a table by value, you would place them into an RWDBInserter:
 
int i = 255;
RWDBInserter insert = myTable.inserter();
insert << 1234 << i;
To read a string and a float from a table, you would extract them from an RWDBReader:
 
RWCString s; float f;
RWDBReader reader = anotherTable.reader();
while (reader()) {
reader >> s >> f;
// process s and f
}
Code in the value layer of the DB Interface Module data model is responsible for converting the literal 1234 and the int i into RWDBTBuffer<T> instances for internal storage, and for converting other RWDBTBuffer<T> instances into application variables. Although this example is simple, it illustrates several features provided by the value layer:
Use of general purpose data types. The example code above uses general purpose data types, ints, floats, and RWCStrings. The database classes RWDBInserter and RWDBReader are used exclusively for data transport; no special types or structures are needed to store the data itself.
Type safety. Database programming is notorious for its lack of type safety. This is mainly because it is impossible to know at compile time which data types belong in which database objects at runtime. By using the DB Interface Module, you can attain runtime type safety; the data model ensures that only type-safe conversions are attempted.
Memory management. Notice that there is no explicit binding of program variables in the example above. In fact, there are no pointers at all. This eliminates a very common cause of error. Explicit variable binding is available when extra control over memory management is desired; however, it should only be used when necessary.
Robustness. There isn't any error checking in the example above. For now, simply note that an application can freely continue in the face of errors, without worrying about crashing because of a lack of error checking. (See Chapter 6, The Error Model.)
The structured data types used in the value layer include:
*RWCString, RWBasicUString, RWWString, RWDateTime, RWTimeTuple, RWTimeTupleOffset, and RWDecimalPortable (from the Essential Tools Module)
*RWDBMBString, RWDBDuration, RWDBBlob, and RWDBValue (from the DB Interface Module)
Classes RWBasicUString, RWWString, and RWDBMBString are briefly described in Chapter 13, Internationalization. The other classes are briefly described in the following sections.