Progress
ADM 2 Guide


Dynamic Query Manipulation

The ADM provides a set of functions that allow you to modify a SmartDataObject’s database query dynamically. These functions modify the query’s WHERE clause in various ways:

The manipulated query is stored in a property and the actual QUERY–PREPARE and QUERY–OPEN do not take place until openQuery( ) is called.

Note that you can also write code to obtain the QueryHandle property and perform your own QUERY–PREPARE. If the SmartDataObject is divided between client and AppServer, such code must be executed on the AppServer for the QueryHandle property to be valid.

The remainder of this section provides more detailed information on the ADM query-manipulation functions. For more information about the WHERE, QUERY–PREPARE, and QUERY–OPEN keywords, see the Progress Language Reference.

The assignQuerySelection( ) function adds field comparison expressions to the query. It supports the majority of standard database queries. With this function:

The addQueryWhere( ) function allows you to add more complex criteria to a query. This function:

The removeQuerySelection( ) function works with field expressions that are added with assignQuerySelection. Specifically, it allows you to remove criteria from the WHERE clause. Fields and operators have separate input parameters.

The columnQuerySelection( ) function also works with field expressions that are added with assignQueryselection. Specifically, it allows you to inspect all of the current criteria for a field, and returns all values added for a particular field as a CHR(1)-separated list of operators and values.

The setQuerySort( ) function changes the SORT phrase.

The setQueryWhere( ) function sets the criteria. It can also be used to add one expression to the query. With this function:

Data Transfer in Queries

Rows are transferred from a database query to a SmartDataObject temp–table, called RowObject, when the first fetch operation takes place. Additional rows are transferred as needed when either of the following operations is performed:

The transfer of rows is performed through the sendRows procedure, which has both a client and a server component in order to support transparently a SmartDataObject that is divided between client and AppServer. The number of rows transferred at a time is determined by the RowsToBatch SmartDataObject property. (The initial value is 200.)

By default, the RowObject data set is built up contiguously starting at the beginning, thus the fetchLast operation causes the retrieval of successive batches of rows until it reaches the end of the data set. For a large data set, this can be a very slow process. Progress Software Corporation recommends that for potentially large data sets, you modify this default behavior by changing the Rebuild On Reposition toggle box in the SmartDataObject instance property dialog box to YES. (This sets the Rebuild On Reposition SmartDataObject property.) The data set is now rebuilt whenever the query is repositioned to a row outside of the current client-side data set.

You use the fetchFirst, fetchNext, fetchPrev, and fetchLast procedures to position within the RowObject table. Once you are positioned on a row, you use the colValues( ) function to return a list of formatted values for the current row. (See the Progress ADM 2 Reference or the online help for details on the format of the values returned.) Whenever the cursor position in the RowObject query changes, the dataAvailable event occurs. (Objects such as SmartDataViewers subscribe to this event.) Additional procedures and functions allow many useful operations, including but not limited to the following:

The following example illustrates how to reposition to a particular record in a SmartDataObject’s query. In this application, the application user can search a database for a customer name. If the application finds the name, it displays the customer information in the SmartDataViewer.

The SmartWindow in this example contains the following SmartObjects:

The application user enters a customer name into the name-search field, then presses the search button. The search button contains the following trigger code:

ON CHOOSE OF BtnSearch DO:
  DEFINE VARIABLE cRowIdent AS CHARACTER NO-UNDO.
  DEFINE VARIABLE cSearch   AS CHARACTER NO-UNDO.
  CSearch = "Name BEGINS ‘" + NameSrch:SCREEN-VALUE + "’".
  CRowIdent = DYNAMIC-FUNCTION(‘rowidWhere’:U IN h_dcustomers, cSearch).
  IF cRowIdent NE ? THEN
  DYNAMIC-FUNCTION(’fetchRowIdent’:U IN h_dcustomers,
  cRowIdent, ‘’:U).
END. 

The rowidWhere function in this code returns the ROWID of the first database query row that satisfies the where clause specified in cSearch. The fetchRowIdent function accepts a comma-separated list of database record ROWIDs for a SmartDataObject row that corresponds to the RowObject’s RowIdent field. If the row is currently in the SmartDataObject’s temp–table, the SmartDataObject repositions to that record, otherwise the database query repositions to that row and rebuilds the temp–table.

After the application repositions the SmartDataObject’s query to the specified customer, it refreshes the SmartDataViewer, displaying the customer data in the SmartDataViewer.

Error Handling

Errors that occur during the transfer of data rows between the database and a visualization object can be detected either on the client side or the server side. If they are detected on the client side, error messages can go directly back to the visualization object. However, errors that are detected on the server side must go back to the visualization object through the SmartDataObject handling the row transfer. For more information on error reporting, see the "Validation Procedures" section.

Initiating Update Operations

The event procedures in visual objects (SmartDataViewers and SmartDataBrowsers) that initiate update operations are as follows:

These procedures are typically invoked from the buttons of an Update SmartPanel or a SmartToolbar. They perform only the parts of their operations that are relevant to the visualization, such as enabling Frame fields or displaying initial values. The actual data update side of the operation occurs in the SmartDataObject, using the following functions:

These functions cause changes to the RowObject table. If the SmartDataObject’s AutoCommit property is set to Yes (the default if no Commit Panel is attached), each row’s changes are automatically written to the database through the Commit( ) function, otherwise they remain in the RowObject table until an explicit Commit is performed.

Getting and Setting Properties

In addition to the standard set and get functions for properties, data.p has a number of support functions to set and get properties of individual columns in the RowObject; for example, Format and DataType. To differentiate these functions from the normal get/set functions for object properties, they are named assignColumnproperty ( column, value ) to assign a value (for those properties that are writable) and columnproperty (column) to retrieve the value.

Signaling Data Availability

The SmartDataObject indicates that data is available by PUBLISHing dataAvailable, and the Data–Target that has SUBSCRIBEd to this event responds appropriately. This happens when the SmartDataObject opens its query and when the cursor position in the query changes. This behavior makes sense for a configuration in which the SmartDataObject and its visualization are part of the same Progress client.

However, if the UI either is not Progress or is in a different process than the SmartDataObject, the Data SmartLink is not present and the dataAvailable event is not sent; you must design your UI objects to deal with this. For example, a visualization could execute the openQuery function in the SmartDataObject by knowing its handle rather than by using an ADM link, and then immediately start requesting data using other functions. If no other outside source is controlling the SmartDataObject, its visualization does not need the Data link or the dataAvailable event; that is, ADM links and event procedures are supported by SmartDataObjects but are not required by other new objects with which they communicate.

Generally, signaling data availability without the Data SmartLink and the dataAvailable event is of interest when you are using SmartDataObjects from a non-Progress environment. Within a 4GL SmartObject application, the ADM manages communication between objects using the link and event, and the code in the ADM super procedures handles this automatically.

Special considerations apply when you access a SmartDataObject from a Java application. For details, see the "Java Applications and SmartDataObjects" section.


Copyright © 2004 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095