Try OpenEdge Now
skip to main content
Web Services
Creating OpenEdge REST Web Services : Data Object Services : Coding Business Entities to implement Data Objects : Sample Business Entity without before-image support
 
Sample Business Entity without before-image support
Following is a sample ABL class defined for a Data Object resource that has no before-image support (and with all annotations removed). It implements the standard Data Object CRUD operations for a Data Object resource defined for a ProDataSet named dsCustomer with the following public methods:
*CreateCreatedsCustomer( )
*ReadReaddsCustomer( )
*UpdateUpdatedsCustomer( )
*DeleteDeletedsCustomer( )
In this case, the ProDataSet contains a single temp-table, eCustomer, with a before-table, beCustomer, that is defined for the Customer table in the sports2000 database. The listing of the data model follows the class.
Note: Although eCustomer has a before-table defined, it is not used to support JSDO before-imaging in this case, since the Data Object resource is defined without before-image support. Instead, it is used to process the appropriate Data Object operation request for the single input record in the ProDataSet, as described below.
All the public methods dispatch their function to private methods that manage the business logic, such as to interpret the filter string passed to the ReaddsCustomer( ) method. The Create, Update, and Delete operations rely on a commitCustomers( ) method to apply the row state from the operation method to the changed record and execute the SAVE-ROW-CHANGES( ) method on the corresponding before-table buffer handle accordingly.
Note: For the Data Object Create, Update, and Delete operations, the input side of the INPUT-OUTPUT DATASET parameter replaces the dsCustomer data left over from any prior operation.
Table 13. Sample Business Entity class for a Data Object resource without before-image support
USING Progress.Lang.*.
BLOCK-LEVEL ON ERROR UNDO, THROW.

CLASS dsCustomer:
  {"dsCustomer.i"}
  DEFINE DATA-SOURCE srcCustomer FOR Customer.

  METHOD PUBLIC VOID ReaddsCustomer(
      INPUT filter AS CHARACTER,
      OUTPUT DATASET dsCustomer):
      THIS-OBJECT:applyFillMethod (INPUT filter).
  END METHOD.

  METHOD PUBLIC VOID CreatedsCustomer(INPUT-OUTPUT DATASET dsCustomer):
    THIS-OBJECT:commitCustomers(INPUT "", ROW-CREATED).
  END METHOD.

  METHOD PUBLIC VOID UpdatedsCustomer(INPUT-OUTPUT DATASET dsCustomer):
    THIS-OBJECT:commitCustomers(INPUT "", ROW-MODIFIED).
  END METHOD.

  METHOD PUBLIC VOID DeletedsCustomer(INPUT-OUTPUT DATASET dsCustomer):
    THIS-OBJECT:commitCustomers(INPUT "", ROW-DELETED).
  END METHOD.

METHOD PRIVATE VOID commitCustomers(INPUT pcFieldMapping AS CHARACTER,
    INPUT piRowState AS INTEGER ):
    DEFINE VARIABLE skipList AS CHARACTER NO-UNDO.

    BUFFER eCustomer:ATTACH-DATA-SOURCE (DATA-SOURCE srcCustomer:HANDLE,
      pcFieldMapping).

    FOR EACH eCustomer.
      BUFFER eCustomer:MARK-ROW-STATE (piRowState).
      IF piRowState = ROW-DELETED THEN
        DELETE eCustomer.
    END.

    /* NOTE:
    ** For the ROW-CREATED case, the database has a trigger that generates
    ** the key value for the new CustNum field. The name of this field is
    ** passed to SAVE-ROW-CHANGES( ) so it will not overwrite the
    ** database-generated value with the unneeded input value.
    */

    IF piRowState = ROW-CREATED THEN
      skipList = "CustNum".

    FOR EACH beCustomer:
      BUFFER beCustomer:SAVE-ROW-CHANGES(1, skipList).
    END.
    
    FINALLY:
      BUFFER eCustomer:DETACH-DATA-SOURCE().
      RETURN.
    END FINALLY.
  END METHOD.

  METHOD PRIVATE VOID applyFillMethod(INPUT pcWhere AS CHARACTER):
    EMPTY TEMP-TABLE eCustomer.  /* Get rid of any existing data */
    BUFFER eCustomer:ATTACH-DATA-SOURCE(DATA-SOURCE srcCustomer:HANDLE).

    IF pcWhere NE "" AND pcWhere NE ? THEN
      DATA-SOURCE srcCustomer:FILL-WHERE-STRING = pcWhere.

    DATASET dsCustomer:FILL().

    FINALLY:
      BUFFER eCustomer:DETACH-DATA-SOURCE().
      DATA-SOURCE srcCustomer:FILL-WHERE-STRING = ?.
      RETURN.
    END FINALLY.
  END METHOD.
  
END CLASS.
Note: Although the client JSDO created for this Data Object resource has no before-image support and sends changes for only a single record at a time, the sample commitCustomers( ) method uses, as a convenience, a FOR EACH statement to mark the row state of the single temp-table record sent from the client, and uses another FOR EACH statement to call SAVE-ROW-CHANGES( ) on the single before-image record to create, update, or delete the record according to its row state.
Following is the dsCustomer.i include file that provides the data model for the dsCustomer class.
Table 14. Data model from dsCustomer.i for the dsCustomer class
DEFINE TEMP-TABLE eCustomer NO-UNDO BEFORE-TABLE beCustomer
  FIELD CustNum AS INTEGER
  FIELD Name AS CHARACTER FORMAT "X(20)"
  FIELD Address AS CHARACTER
  FIELD Phone AS CHARACTER
  FIELD SalesRep AS CHARACTER
  FIELD CreditLimit AS DECIMAL
  FIELD Balance AS DECIMAL
  FIELD State AS CHAR
  FIELD numOrders AS INT
  INDEX CustNum IS UNIQUE PRIMARY CustNum
  INDEX Name NAME.
DEFINE DATASET dsCustomer FOR eCustomer.