Progress
AppBuilder
Developer’s Guide
Data Validation Limitation
You can choose to add data-validation procedures to your SmartDataObject. These optional procedures can operate at the column, row, or transaction level. If you do choose to create such routines, you must create them as internal procedures. Because the SmartDataObject calls these procedures automatically, you must follow the expected naming and error-handling conventions. See the Progress ADM 2 Guide and the Progress ADM 2 Reference for details.
SmartDataObjects have the DB–AWARE flag set. For DB–AWARE objects, AppBuilder sets the DB–REQUIRED flag in all new internal procedures, including validation procedures. Generally this is appropriate and useful. In one specific set of circumstances, however, it is not, and you will have to explicitly turn off the DB–REQUIRED flag. Those conditions are:
- The application will run on an AppServer. Applications that do not run on an AppServer are not affected. Note that good practice suggests that you always design for the greatest flexibility of use.
- The client program does not require a local database connection via a SmartDataObject. Client programs that must have such a local connection in order to run are not affected. Note that good practice suggests that you always account for the case of no local connection.
- Your routines validate rows or columns (fieldnameValidate(), RowObjectValidate()). Routines that validate whole transactions (TransactionValidate()) are not affected.
The problem comes about because all DB–REQUIRED routines are removed from the client-only version of the SmartDataObject during compilation. This allows the program to load and run in the absence of a database connection. If your validation routines are marked DB–REQUIRED, then they, too, will be removed.
Normally, calling a non-existent routine would cause a run-time error. But calls to optional routines never complain if they fail, and validation routines are always optional. The net result is that, when the client-only object is loaded, database updates are carried out without client-side validation checks even though you wrote the routines to perform them. Neither the compiler nor the interpreter can detect this logical error.
Solving the Problem
- Divide your validation tasks according to whether they require a database lookup operation. References to RowObject or other temp-tables do not count as lookup operations.
- Write your fieldnameValidate() and RowObjectValidate() procedures to include only the validation operations that do not require lookup. Do not include direct references to a database in these procedures, and turn off the DB–REQUIRED flag in them. AppBuilder offers a convenient option in the Section Editor for this purpose.
- Put any validation operations requiring lookup into one of the TransactionValidate() procedures. Keep the DB–REQUIRED flag turned on in these procedures.
By writing your fieldnameValidate( ) and RowObjectValidate( ) procedures such that you can legitimately turn off the DB–REQUIRED flag in them, you ensure that these routines will survive compilation and that all validation will occur as you intend.
Forcing Server-side Validation
It is generally more efficient to do row and column validation on the client side, as part of SubmitRow(). There are some cases where this is not possible—such as calling a SmartDataObject from a Java program where no client-side version of the object exists. You would then want to force all validation, including row/column validation, to take place on the server. You can do this with a single line of code.
This code also works in the case where there is a client. In that case, the client-side validation operations take place first on the client side, and then a second time on the server side. This introduces some inefficiency, but is not otherwise harmful.
To force all validation to take place on the server, regardless of whether it also takes place in the client, follow these steps:
- Open your SmartDataObject master for editing. It will appear on your display:
![]()
- Choose Window
Code Section Editor, and then select Procedures from the sections list.
- Create a new procedure called initializeObject( ) —or edit the existing procedure by that name, if you already created it—and include in it this line:
- Save your work.
All instances made from the SmartDataObject master you just changed will now perform all row/column validation on the client side—if there is a client—and on the server side too.
Copyright © 2004 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |