skip to main content
OpenEdge Development: ADM and SmartObjects
Developing Your Application's Business Logic : SmartDataObject query and update operations
 
SmartDataObject query and update operations
SmartDataViewers and SmartDataBrowsers provide the display and browse capabilities that make the data retrieved by a database query accessible to an application user; however, these SmartObjects never directly access a database. The query and update operations that do access the database are performed, instead, by a SmartDataObject to which the SmartDataViewer or SmartDataBrowser is linked. The SmartDataObject manages query and update operations using two automatically created Progress temp-tables, RowObject and RowObjUpd, which serve as data repositories within the application. Figure 7–1 illustrates data flow among a database, a SmartDataObject and its temp-tables, and a client object of the SmartDataObject, in this case a SmartDataViewer.
Figure 7–1: The SmartDataObject and its temp-tables
The following sections discuss how the SmartDataObject uses the RowObject and RowObjUpd temp-tables in query and update operations. A subsequent section describes special fields in the RowObject and RowObjUpd temp-tables.
Query operations and the RowObject temp-table
The SmartDataObject accesses a database using its own database query. Progress transfers the result set retrieved through the query into the SmartDataObject’s RowObject temp-table, which contains the columns defined for the SmartDataObject. The data in the temp-table is the access mechanism for all visualizations or other objects that use the SmartDataObject. Client objects see only the columns in RowObject, receive column values only from RowObject, and return updated values and new rows only to RowObject.
The SmartDataObject uses the RowObject temp-table to manage data in both non‑distributed and distributed mode. In distributed mode, the use of this temp-table allows the SmartDataObject to operate in any of these configurations:
*Run in a Progress client session with a direct connection to the database
*Run split between a client object and a server object running on an AppServer
*Run entirely on an AppServer
A SmartDataObject that operates as part of a client‑side SmartDataObject application is a Navigation-Target, so it responds to repositioning commands such as fetchNext. It also can be a Data-Source, passing values from its RowObject temp-table to other objects for display and update. In addition, it can be a Data-Target, so it can receive key field values from other SmartDataObjects and use them in defining its own query.
Update operations and the RowObjUpd temp-table
SmartDataObject update operations require an additional Progress temp-table called RowObjUpd. This temp-table, a copy of the RowObject temp-table, is used for handling all types of changes to data rows: updating existing rows, adding rows, and deleting rows:
*When an existing row is updated, Progress creates in RowObjUpd a before image of the row; that is, the row with its original row values, as it appeared before the update. When the update is committed, the updated version of the row also is written to the RowObjUpd table. The server‑side code uses the before image to verify that the row’s data was not changed by another user since it was read, then uses the new values to update the database.
*When a row is added and the add is committed, the new row is written to the RowObjUpd table.
*When a row is deleted, the deleted row is removed from the RowObject table and written to the RowObjUpd table to be passed to the server.
The SmartDataObject transfers updated and newly added rows back to the database when it receives a Commit request. Depending on how the SmartDataObject’s AutoCommit property is set, the commit can be performed either automatically when an update is received (the default behavior) or when a specific Commit request is received after a set of updates are made. The default behavior is the typical usage; however, to change to the nondefault behavior, set the SmartDataObject’s AutoCommit property to NO. For details, see the “Commit SmartPanel” section.
When a change is committed, the RowObjUpd temp-table is passed back to the server (if the SmartDataObject is divided between client and AppServer), and the code in serverCommit reads the table and makes the appropriate changes to the database. For details, see the field description of RowMod in the “Nondata fields in the RowObject and RowObjUpd temp-tables” section.
Nondata fields in the RowObject and RowObjUpd temp-tables
A RowObject temp-table contains more than just fields selected from database tables. It also contains the following information:
*A temp-table definition (the first line of the table)
*Field definitions for the temp-table data (corresponds to the database data)
*Field definitions for the temp-table itself
*Index definitions
For example:
 
DEFINE TEMP-TABLE RowObject RCODE-INFORMATION
  FIELD CustNum LIKE Customer.CustNum VALIDATE ~
  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 ~
 
  FIELD RowNum   AS INTEGER
  FIELD RowIdent AS CHARACTER
  FIELD RowMod   AS CHARACTER
 
  INDEX RowNum   IS PRIMARY RowNum
  INDEX RowMod   RowMod
  INDEX RowIdent RowIdent.
The RowObject temp-table contains three special fields, RowNum, RowIdent, and RowMod. These fields. which are maintained by the SmartDataObject support code, are used to manage queries and updates as follows:
*RowNum — An integer value that represents the sequence number of the row within the query’s result set. A unique value is assigned to each row as it is added to the table; basically it is used to keep the rows in a consistent sort order. The values begin arbitrarily with 900,000, which generally assures that the values of this field remain positive whether the temp-table is built forward or backward.
*RowIdent — A character field that contains a comma‑separated list of the ROWIDs of the database records from which the RowObject row is derived. The database ROWIDs are used to re‑retrieve the records from the database when performing an update. If the records in the RowObject temp-table result from a join, the ROWIDs in this field are a combination of the ROWIDs for the joined tables.
*RowMod — A character field that contains a one‑character code that indicates the kind of update operation performed on a row:
*For a newly added row, RowMod is set to A if the row results from an Add operation or C if it is results from a Copy operation.
*For a row that is to be deleted, RowMod is set to D.
*An Update operation returns two rows: a copy of the row as it was received, for which RowMod is set to “”, and the row with its changes, for which RowMod is set to U. The copy of the row as received is used to verify that the corresponding database records were not changed since the user accessed the row, and the row with changes is used to update the database.
The RowObjUpd temp-table contains the same fields as the RowObject temp-table plus the ChangedFields field, which is used only for updates:
*ChangedFields (RowObjUpd temp-table only) — A character field that contains a comma‑separated list of the names of all SmartDataObject columns in the current row that were modified. This list is used to ensure that only those fields that were not changed previously are written back to the database, to minimize interference between different users of an application who might be changing different fields in the same record. This field is maintained automatically by the SmartDataObject support code, regardless of how each field’s value may have been changed.