Progress
Language Tutorial
for Character
The DISPLAY, ENABLE, and ASSIGN Technique
When you worked with variables in previous chapters, you used this technique, as summarized below:
Using the form in Figure 8–9, you could follow the same sequence of steps to change database data. Choosing the Update button will be the event that copies the current screen buffer to the record buffer and eventually to the database.
To use this basic technique with database records, you need to learn more about locks, ROWIDs, ENABLE, and ASSIGN.
Locks
The technique listed above may not work well with database records because of the possibility that more than one user might try to use a record at the same time. Since most Progress applications are designed to work with multiple users, this technique needs modification to support multi-user mode. The Progress RDBMS has two basic rules for a database in multi-user mode:
When a user retrieves a record, Progress puts the user’s copy of the record in one of three lock states. A lock is a description on the user’s freedom to use the record. Progress has three keywords that describe the lock states, as shown in Table 8–2.
To let the greatest number of users successfully access a particular record, it makes sense to keep the record in NO-LOCK state. The application should only upgrade the lock to EXCLUSIVE-LOCK during the act of changing data. This means that the record is tied up for the shortest possible period of time.
Row IDs (ROWID)
Every record (or row) in a database has a unique internal identifier which is specified by the Progress keyword ROWID. ROWIDs let you identify a particular record quickly and easily.
To work with ROWIDs, you have to get them and store them. Progress supports ROWIDs as a separate data type, which you can specify in a variable definition with the keyword ROWID. To retrieve a ROWID, you can use the ROWID( ) function.
This code fragment shows how to retrieve and store a ROWID for later use:
The programming example at the end of this section demonstrates how to use ROWIDs and how to take specific control over locks. First, you need a more in-depth look at the ENABLE and ASSIGN statements.
ENABLE Statement
You saw in the last section that the DISPLAY statement moves data from the record buffer to the screen buffer. ENABLE allows users to enter data directly into the screen buffer, as shown in Figure 8–10.
Figure 8–10: Data Movement with the ENABLE Statement
![]()
This is a partial syntax for the ENABLE statement.
Use the EXCEPT widget syntax to enable all the widgets in a frame, except for those you specify.
ASSIGN Statement
You also have encountered the ASSIGN statement. ASSIGN moves data from the screen buffer to the record buffer, as shown in Figure 8–11.
Figure 8–11: Data Movement with the ASSIGN Statement
![]()
Once you move changes from the screen buffer to the record buffer, or make changes directly to the record buffer, Progress understands that you want those changes written to the database. Progress does not immediately write the changes to the database. When the write occurs is based on other factors. The next section describes how Progress handles database writes.
This is the syntax for the ASSIGN statement.
You can assign fields or the entire record. The EXCEPT syntax is also valid with ASSIGN.
By using DISPLAY, ENABLE, and ASSIGN together, you create a chain of functionality that presents current data to your users, allows them to change it, and allows them to save the changes.
NOTE: Using the DISPLAY, ENABLE, and ASSIGN technique does not automatically invoke the validation behaviors stored in the Data Dictionary. To force the validation routines to run, you can query the VALIDATION attribute of a widget or frame. For more information, see the Progress Programming Handbook . The other techniques described in this section do invoke Data Dictionary validation.DISPLAY, ENABLE, and ASSIGN Programming Example
Follow these steps for a demonstration of the DISPLAY, ENABLE, and ASSIGN technique with explicit control of locks:
- Open
lt-08-03.p
and run it. Note that the form now uses fill-ins instead of text widgets.- Select a record and change some of the fields.
- Choose the Next followed by the Prev button. The record does not contain the new data. This procedure does not save your changes unless you choose the Update button.
- Select a record, change some of the fields, and choose Update.
- Choose the Next followed by the Prev button. The new data is now permanent.
- Choose Exit, then press SPACEBAR to return to the Procedure Editor.
Here is the code that created the display:
The following notes help to explain the code:
- In the main code block, the OPEN QUERY statement contains the NO-LOCK option. This means that navigating through the records or leaving the application running will not impede other users.
- The fields in this example are specifically enabled.
- This variable will hold the current ROWID when trying to upgrade a lock.
- This include file contains the navigation triggers which you have already studied.
- Once the user chooses Update, this trigger executes. Here, the trigger saves the ROWID of the current Item record.
- Recall that FIND retrieves an individual record. This trigger uses FIND to get a copy of the record with the EXCLUSIVE-LOCK option. The FIND statement does not affect the defined query.
- If any other user has EXCLUSIVE-LOCK or SHARE-LOCK, the FIND will fail, which is why this IF statement checks the record buffer. If the record is there, the user’s changes are saved with the ASSIGN statement.
- If the FIND failed, then refind the record with a NO-LOCK and inform the user.
One way to keep data accessible to all users is to keep the data in NO-LOCK and let the user change it. When it is time to assign the changes, use the FIND CURRENT or GET CURRENT statement to get a fresh copy of the record that the user has been modifying with an EXCLUSIVE-LOCK. Then, use the CURRENT-CHANGED function to test for changes to the record while the user was working with it. If the record was changed by another user, you can send a message to the user and display the updated record. If the record is unchanged, you can assign the changes.
You can use this trigger code in place of the trigger code for btn-Update in
lt-08-03.p
as the following code fragment illustrates:
Copyright © 2004 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |