skip to main content
OpenEdge Development: ADM and SmartObjects
Data Management in the ADM : Displaying and browsing data sets
 
Displaying and browsing data sets
The SmartDataObject accesses data. SmartDataViewers and SmartDataBrowsers provide various display and browse capabilities for the data sets accessed by the SmartDataObjects to which they are linked:
*A SmartDataObject manages a database query on one or more tables that can be distributed across the AppServer. It defines and retrieves a set of database records.
*A SmartDataViewer views column values it receives from another object, like a SmartDataObject, that is accessing the database. A SmartDataObject and SmartDataViewer, together with a SmartPanel, can retrieve, display, navigate, and update records.
*A SmartDataBrowser allows an application user to browse column values it receives from another object, like a SmartDataObject, that is accessing the database. A SmartDataBrowser also may allow updates to data.
A SmartDataObject has its own database query. A SmartDataObject can pass a key value from one query object to a subordinate object, so the second object can open a query dependent on that key value; for example, Orders OF a particular Customer. For more information, see the “Initializing the foreign key fields” section.
All database queries can be modified dynamically so a given SmartDataObject can be used in various application contexts. For example, a SmartDataObject whose query definition is FOR EACH Order might be used in one application context to display and manage all Orders, but in another context, it might be made into a dependent query object that receives a Cust-Num key from another Customer SmartDataObject and opens its query as FOR EACH Order WHERE Cust-Num = key value.
SmartDataObjects
The SmartDataObject accesses a database directly. It transfers rows, as defined by its database query, to a temp-table called RowObject, one batch at a time. (Fields from one or more tables can be joined into a single result table.) For a discussion of the RowObject temp-table, see the “SmartDataObject query and update operations” section.
Once the RowObject temp-table is built, the SmartDataObject presents its rows to SmartDataViewers, SmartDataBrowsers, and other client objects. The SmartDataObject thus insulates the client objects from the database specifics.
When a SmartDataObject reads a data set into a RowObject temp-table, it provides essentially a snapshot of the current state of the data set, often called a view. The RowObject temp-table does not necessarily reflect updates to the data set that are made by other users in another session; however, any code that executes the openQuery procedure on the data set automatically refreshes the RowObject temp-table with the latest data. Alternately, you can use the refreshRow function on the current row to get the latest data.
You can customize various field‑related properties of a SmartDataObject to meet your own application needs:
*Select which fields will be a part of the data set presented to other client objects.
*Change the field names.
*Determine which fields the SmartDataObject allows client objects to update.
*Change formats and other field attributes.
*Use calculated fields to express a calculation based on other fields in the RowObject temp-table or as a placeholder for information to be passed to or from client objects that use the SmartDataObject.
SmartDataObjects support update validation logic beyond that defined in the Data Dictionary or in database triggers. For more information, see Chapter 7, “Developing Your Application's Business Logic.”
SmartDataViewers
A SmartDataViewer does not define or open a query; therefore, it always relies on another SmartObject for data. SmartDataViewers never FIND a database record, and no record buffers are passed to it. This helps separate the user interface from the data management and does not constrain SmartDataViewers to run in a session with a database connection. A SmartDataViewer never has any database records at run time; it displays data from a query defined elsewhere. As with the SmartDataBrowser, all updates must be performed through a SmartDataObject.
SmartDataBrowsers
You build a SmartDataBrowser against a SmartDataObject, selecting fields from that SmartDataObject. The SmartDataBrowser browses the SmartDataObject query at run time. In the same way as a SmartDataViewer, the SmartDataBrowser does not actually have any database records at run time; it is browsing a query defined elsewhere. Also, as with the SmartDataViewer, updates to a SmartDataBrowser simply cause modified values to be passed to the SmartDataObject for updating. This method of building a SmartDataBrowser maintains independence of the user interface from the database, since the SmartDataBrowser browses a temp-table query maintained in another object.
Recall there are two types of SmartDataBrowsers: dynamic and static. The dynamic SmartDataBrowser is more versatile; it can be configured to display and update the query of any SmartDataObject, unlike a static SmartDataBrowser, which is specific to a particular SmartDataObject. The dynamic SmartDataBrowser displays and updates records from a set of fields determined at run time (rather than at design time, as is the case for the static SmartDataBrowser) and takes its query at run time from the SmartDataObject to which it is linked.
Initializing the foreign key fields
ForeignFields is a SmartDataObject property that is set at design time to designate which of its fields to map to foreign key fields in a SmartDataObject that is its parent. A corresponding property called ForeignValues holds the values of those fields for the current row. When ForeignFields is set for a particular SmartDataObject, performing the Add or Copy operation in that SmartDataObject assigns the values of the key fields to the corresponding fields in the newly added row.
Suppose you have two SmartDataObjects, CUST and ORDER, that are set up as follows:
*CUST parents ORDER.
*Both these SmartDataObjects have a cust-num field.
*The ForeignFields property in ORDER is set to the cust-num field.
*The current value of cust-num (and, therefore, the ForeignValues property in the ORDERCUST SmartDataObject) is 27.
Figure 4–1 illustrates this setup.
Figure 4–1: Inheriting foreign key field values
As the application user adds orders, the value of the ORDER SmartDataObject’s cust-num field is automatically set to the current value of the CUST SmartDataObject’s cust‑num field; that is, 27. This is done in the addRow function of data.p to display the ForeignField value as the initial value for the new row. If the application user does not change that value (and such fields normally cannot be updated), the initial value is assigned to the new row in the procedure submitForeignField, called from the function submitRow during the Save operation. See the online help for descriptions of these functions,
Compatibility checking
When you instantiate a static SmartDataBrowser or a SmartDataViewer in a Progress application, the AppBuilder must be able to check whether the fields to be browsed or displayed in the SmartObject match (are compatible with) those of the SmartDataObject to which you will link it. Depending on the SmartObject type, the AppBuilder uses either signatures or field lists to perform this check. (Compatibility checking is not required for dynamic SmartDataBrowsers.)
Signature and field‑list checking at design time
The AppBuilder performs a compatibility check in the following circumstances:
*When you instantiate a SmartDataBrowser or SmartDataViewer in a SmartContainer. The AppBuilder checks all SmartDataObjects in the SmartContainer, to see whether their signatures and field lists match those of the new SmartDataBrowser or SmartDataViewer, respectively. If any matches occur, the Progress Advisor asks which, if any, SmartDataObjects to link to the SmartDataBrowser or SmartDataViewer. If there are no matches, the Advisor does not appear.
*When you instantiate a SmartDataObject in a SmartContainer. The AppBuilder checks all existing SmartDataBrowsers and SmartDataViewers in the SmartContainer to see whether their signatures and field lists, respectively, match those of the new SmartDataObject. If any matches occur, the Progress Advisor asks which, if any, SmartDataBrowsers or SmartDataViewers to link to the SmartDataObject. If there are no matches, the Advisor does not appear.
*When you modify a SmartDataObject. The AppBuilder checks all objects linked to that SmartDataObject for compatibility, and the Progress Advisor notes any incompatibilities.
*When you modify a SmartDataBrowser or SmartDataViewer that is linked to a SmartDataObject. The AppBuilder checks for compatibility, and the Progress Advisor notes any incompatibilities.
You can verify the validity of the signatures of linked objects by clicking on the Check Links button in the SmartLinks window. (See OpenEdge® Development: AppBuilder for details.)
Checking SmartDataBrowser compatibility
Compatibility checking is not required for dynamic SmartDataBrowsers. A dynamic SmartDataBrowser simply attaches to the query of its SmartDataObject and generates a column list at run time, thus avoiding the necessity for a compatibility check.
Compatibility checking for static SmartDataBrowsers uses signatures. As in the case of a SmartDataObject, the temp-table definition of a SmartDataBrowser gives it a unique signature that identifies the order, number, and data types of its fields. The exact use of the signature differs depending on what action is attempted and against which objects the action occurs.
In a compatibility check, the getDataSignature function for both the SmartDataObject and static SmartDataBrowser returns a character string with a representation of the object’s signature. The signature of the SmartDataObject is compared to the signature of the static SmartDataBrowser to see whether they are compatible. If so, the static SmartDataBrowser can browse the SmartDataObject’s query when the objects are linked at run time.
Checking SmartDataViewer compatibility
The field‑matching relationship of a SmartDataViewer with a SmartDataObject against which it is built is different from that of a SmartDataBrowser with a SmartDataObject. The AppBuilder uses the SmartDataViewer’s displayed field list, rather than a signature, to determine compatibility with the SmartDataObject. This displayed field list is defined by the SmartDataViewer’s displayed fields and accessed with the getDisplayedFields function. If a SmartDataViewer’s displayed fields are the same as or a subset of a SmartDataObject’s fields, the objects are considered to have a matching displayed field signature. A SmartDataViewer can successfully retrieve data from a SmartDataObject only if the SmartDataObject can provide all of the fields that the SmartDataViewer needs.
Similarly, a SmartDataViewer has an enabled field list that is defined by its enabled fields and accessed with the getEnabledFields function. If a SmartDataViewer’s enabled fields are the same as or a subset of a SmartDataObject’s updateable fields, the objects are considered to match, according to this enabled field list. A SmartDataViewer can successfully send data to a SmartDataObject only if the SmartDataObject can update all fields the SmartDataViewer provides.
Example: SmartDataObject and SmartDataViewer. The SmartDataObject dcust.w generates the following include file:
 
dcust.i
FIELD Name LIKE Customer.Name VALIDATE~
FIELD Address LIKE Customer.Address VALIDATE~
FIELD City LIKE Customer.City VALIDATE~
FIELD State LIKE Customer.State VALIDATE~
FIELD PostalCode LIKE Customer.PostalCode VALIDATE~
. . .
The updateable fields in this file are Name, Address, and City.
Suppose a SmartDataViewer built against dcust.w enables the Name and Address fields. In this case:
*The SmartDataViewer has a matching displayed field list with the SmartDataObject.
*The SmartDataViewer has a matching enabled field list with the SmartDataObject.
Now, suppose the SmartDataViewer built against dcust.w enables the Name and Postal‑Code fields. In this case:
*The SmartDataViewer has a matching displayed field list with the SmartDataObject.
*The SmartDataViewer does not have a matching enabled field list with the SmartDataObject. This is because the SmartDataObject’s PostalCode field is not updateable.
Example: SmartDataObjects with Contrasting Signatures. The SmartDataObject dcust.w generates the following include file:
 
dcust.i
FIELD Name LIKE Customer.Name VALIDATE~
FIELD Address LIKE Customer.Address VALIDATE~
FIELD City LIKE Customer.City VALIDATE~
FIELD State LIKE Customer.State VALIDATE~
FIELD PostalCode LIKE Customer.PostalCode VALIDATE~
. . .
In contrast, the SmartDataObject d-custreverse.w generates the following include file:
 
dcustreverse.i
FIELD PostalCode LIKE Customer.PostalCode VALIDATE
FIELD State LIKE Customer.State VALIDATE~
FIELD City LIKE Customer.City VALIDATE~
FIELD Address LIKE Customer.Address VALIDATE~
FIELD Name LIKE Customer.Name VALIDATE~
. . .
In this example:
*A SmartDataBrowser built against the dcust.w SmartDataObject will not match the d-custreverse.w SmartDataObject. This is because the temp-table signature is used to determine compatibility and the order of the fields is different.
*A SmartDataViewer built against the dcust.w SmartDataObject will match the d-custreverse.w SmartDataObject. This is because the displayed field list is used to determine compatibility and the order of the fields does not matter, only their names and data types.
Using Data SmartLinks
Data in the form of field values is passed from one SmartObject to another using a Data SmartLink. A SmartDataObject can be a Data-Source for another object. It also can be a Data-Target, receiving a key value from another query object to use in opening a query. Visual objects such as SmartDataViewers and SmartDataBrowsers also can be Data-Targets. A SmartDataViewer as a Data-Target receives formatted column values from a SmartDataObject for display. A SmartDataBrowser as a Data-Target browses its Data-Source’s query and displays column values in its browse.
At design time, when you drop a SmartObject into an application, the AppBuilder’s Link Advisor assesses each SmartObject already in the application to determine whether it is suitable for a Data link connection with the new SmartObject and, if it is, it recommends the connection. It makes its assessment by examining the properties of each object to determine what columns it defines: a query object can be a Data-Source for another object only if it can supply one or more columns that the object could use as a key to open its own query.
In particular:
*A query object can be a Data-Source for a visual object such as a SmartDataViewer if all fields displayed by the SmartDataViewer are in the query object and all fields enabled in the SmartDataViewer are updateable in the Data-Source.
*A SmartDataBrowser can be a Data-Target only for a SmartDataObject with the same signature.
Note: Because of the flexibility of SmartObject combinations and the dynamic nature of queries, the Link Advisor might suggest possible links that are not desirable for your application. Always examine Link Advisor recommendations before accepting them. One way to avoid problems is to drop Data-Sources onto the design window before Data-Targets. When two objects can be linked in either direction, the Link Advisor assumes that the first object dropped into the application should be the Data-Source.