Suppose you are writing an application that accesses data in an Oracle
database. You have obtained a dynaset on a set of records and are writing a graphical
user interface program to access those records. As you navigate through, add,
or delete records, you want the value of some column to be reflected in some
object such as a variable or, more typically, in an edit control user interface
widget. Much bookkeeping is involved in such programming: when to get new values
for the column objects, when to clear them, when to put their changed values
into the Oracle database, and so forth.
The OBinder and OBound classes solve this problem. An instance of the OBinder class functions as the bookkeeper. You tell it the SQL query and it manages
the dynaset. If you want, it can also manage the database object. Then, you
"bind" instances of OBound objects to the OBinder instance. Each OBound object becomes bound to a particular column in the query. At appropriate
times, the OBound object is told its new value (for example, after navigation to a new record).
The OBound object tells the OBinder when the value has been changed (for example, when the text of a edit control
has been modified). Later, again at the appropriate time, the OBound object is told when to save the data to the Oracle database.
OBound objects display data, allow changes to data, and note when changes are made.
At the time the first change occurs, an ODynaset::StartEdit call is made to begin editing the record. This may fail (for example, for
reasons of privilege; see the StartEdit documentation). If a record has been changed and the dynaset attempts to move
to another record, the values in the changed record are set, by way of calls
to OBound::SaveChange, and the record updated.
Users familiar with Visual Basic will notice that the OBinder instance functions as a VB data control (though it has no user interface),
and the OBound instances function as VB bound controls.
You never actually declare instances of OBound objects. OBound is always subclassed. (See the OBound documentation for more information.)
Often you need to modify the specific behavior of the OBinder class. The power of C++ virtual functions are valuable in such situations.
For most common operations, a "trigger" function is called both before and after
the operation is performed. You can change the behavior of the OBinder class by overriding various trigger functions. The OBinder class and the OBound class have separate trigger functions, so that behavior can be overridden at
either the query level or at the individual bound object level. ("Triggers"
will be familiar to users who have developed using Oracle Forms. The OBinder triggers correspond to block-level triggers; the OBound triggers correspond to item-level triggers.)
Consider a typical example:
You have built a form in which each column in a table is represented by an
edit control - that is, each column is bound to a text widget subclass of OBound (such subclasses of OBound are provided in the OMFC libraries). When a new record is added, you want a
default value set for the "color" column. You would make your own subclass of
the OBound class, overriding the PostAdd trigger method. You would then change your code so that the color column is
bound to this new subclass. Then, after a new record is added, your method would
be called. (More concrete examples are provided in the Workbook.)
The times that the various trigger methods are called is documented in the
section "OBinder Trigger Methods". OBinder trigger methods are always called before OBound triggers. Then, every OBound object’s equivalent trigger is called. The object that was bound first has its
trigger called first, the second object bound has its trigger called second, and so
on. If at any time a trigger method returns an OFAILURE return, no more triggers
are called. If this is a pretrigger, an OFAILURE return also cancels the
action.
There is no method in OBinder to bind OBound objects. To bind OBound objects, use the BindToBinder method of the OBound class.
The OBinder class supports the following methods:
Construction and destruction:
OBinder
~OBinder
Attributes: