Using JSDOs to create mobile and web clients : Accessing standard CRUD and Submit operations
  

Accessing standard CRUD and Submit operations

After creating a JSDO for a dsCustomer resource as explained in the preceding section, you can use standard JSDO methods to read, create, update, and delete records. The sections that follow provide guidance and examples for each of these operations.
Of the currently supported Progress Data Object Services (OpenEdge and Rollbase), only OpenEdge Data Object Services can require significant coding to implement server-side Data Objects. Therefore, the information on the JSDO in these examples refers to OpenEdge ABL used to implement an OpenEdge Data Object created for an OpenEdge DataSet (ProDataSet) resource named dsCustomer, which can support one or more OpenEdge temp-tables. For more information on using ABL to implement OpenEdge Data Objects, see the OpenEdge documentation on both using ABL and implementing Data Objects, including the information on Data Object Services in OpenEdge Development: Web Services. If you have no role in implementing OpenEdge Data Objects, or your JSDOs access only Rollbase Data Ojbects, you can ignore these ABL references.
For a Rollbase Data Object, each available resource is created for a single available Rollbase object, which is equivalent to a single database table, and the implementation of the Data Object itself is provided automatically by the Rollbase cloud server.
For an OpenEdge Data Object, the ABL methods in the following examples are from an OpenEdge Business Entity that is implemented as a singleton class with the following common code elements:
*Inheritance — The OpenEdge-defined abstract class, OpenEdge.BusinessLogic.BusinessEntity, which defines inherited ABL methods that the Business Entity calls to implement the standard Data Object CRUD and Submit operations on the dsCustomer resource with before-image support:
*CreateCreateData( ), called by CreatedsCustomer( )
*ReadReadData( ), called by ReaddsCustomer( )
*UpdateUpdateData( ), called by UpdatedsCustomer( )
*DeleteDeleteData( ), called by DeletedsCustomer( )
*SubmitSubmitData( ), called by SubmitdsCustomer( )
*Resource data model — A before-image enabled ProDataSet defined with a single temp-table that is based on the Customer table of the OpenEdge-installed sports2000 database:
Table 7. Data model for the dsCustomer resource
DEFINE TEMP-TABLE ttCustomer BEFORE-TABLE bttCustomer
FIELD Address AS CHARACTER LABEL "Address"
FIELD Balance AS DECIMAL INITIAL "0" LABEL "Balance"
FIELD City AS CHARACTER LABEL "City"
FIELD CustNum AS INTEGER INITIAL "0" LABEL "Cust Num"
FIELD Name AS CHARACTER LABEL "Name"
FIELD Phone AS CHARACTER LABEL "Phone"
FIELD State AS CHARACTER LABEL "State"
INDEX CustNum CustNum
INDEX Name Name.

DEFINE DATASET dsCustomer FOR ttCustomer.
*Additional Business Entity class definitions — Where customer.i is an include file that defines the resource data model (see above) and the class supports before-imaging and all the standard Data Object operations (with all tool annotations removed):
Table 8. Business Entity class class definitions
USING Progress.Lang.*.
USING OpenEdge.BusinessLogic.BusinessEntity.


BLOCK-LEVEL ON ERROR UNDO, THROW.


CLASS Customer INHERITS BusinessEntity:

{"customer.i"}

DEFINE DATA-SOURCE srcCustomer FOR Customer.

CONSTRUCTOR PUBLIC Customer():

DEFINE VAR hDataSourceArray AS HANDLE NO-UNDO EXTENT 1.
DEFINE VAR cSkipListArray AS CHARACTER NO-UNDO EXTENT 1.

SUPER(DATASET dsCustomer:HANDLE).

/* Data Source for each table in dataset. Should be in table order
as defined in DataSet. */
hDataSourceArray[1] = DATA-SOURCE srcCustomer:HANDLE.

/* Skip-list entry for each table in dataset. Should be in temp-table order
as defined in DataSet. Each skip-list entry is a comma-separated list of
field names, to be ignored in the ABL CREATE statement. */
cSkipListArray[1] = "CustNum".

THIS-OBJECT:ProDataSource = hDataSourceArray.
THIS-OBJECT:SkipList = cSkipListArray.

END CONSTRUCTOR.

/* Methods to implement the
standard Data Object operations . . . */

END CLASS.
This Business Entity class and its constructor define and initialize an ABL handle array (hDataSourceArray) with a DATA-SOURCE reference to the single OpenEdge database table (Customer) that provides the initial data for the dsCustomer ProDataSet. If dsCustomer contained multiple temp-tables, the constructor would initialize this array with a DATA-SOURCE reference for each database table that provides the data.
The constructor also defines and initializes a character array (cSkipListArray) that contains an array of comma-separated lists, each of which is a list of fields in each temp-table that and CUD and Submit operations should ignore, because their values are updated by database triggers or other server code. You need to specify as many lists (null strings, if empty) as there are temp-tables, and in the order that the temp-tables appear in the ProDataset.
Finally, the Business Entity constructor, first passes the ProDataSet dsCustomer handle to its super constructor and sets the two super-class-defined properties, ProDataSource and SkipList to the two arrays that it has initialized. The Business Entity then defines the ABL methods that implement the supported Data Object operations, which you can see described under the following topics.
Note: The OpenEdge Business Entity described, here, uses the most basic OpenEdge features to implement an OpenEdge resource with before-imaging, which a JSDO can access in most client environments other than the Telerik Platform. If you are using the Telerik Platform to build a mobile app or want to access the Business Entity as a Rollbase external object, this Business Entity must be revised as described for updating Business Entities for access by Telerik DataSources and Rollbase external objects in OpenEdge Development: Web Services.
To access the standard Data Object operations on a given resource using the JSDO, a client typically follows an iterative procedure that includes these general steps:
1. Reads resource data into JSDO memory using the fill( ) method to send a Read operation across the network along with optional selection criteria passed as a parameter according to Data Object resource requirements and the platform used to implement the client application. The client handles the results using JSDO events or Promises, depending on the availability of Promises and client application requirements.
2. If the resource is writable (not read-only), creates, updates, and deletes any number of record objects in JSDO memory calling the JSDO add( ), assign( ) (or its equivalent), and remove( ) methods, respectively. This marks each affected record in JSDO memory as a pending record create, update, or delete. For more information, see the description of the add( ) method, assign( ) method (JSDO class), or remove( ) method.
3. Synchronizes any pending changes in JSDO memory with the corresponding server Data Object and its database, depending on the type of Progress Data Object Service and its implementation. The client invokes this data synchronization by calling the JSDO saveChanges( ) method in one of the following ways, depending on the Data Object resource implementation:
*If the resource does not support Submit, the client calls saveChanges( ) with either a single argument of false or an empty parameter list (the default). This call sends one or more Create, Update, or Delete (CUD) operation requests across the network, with one operation request sent across the network for each pending record change in JSDO memory. Thus, the respective CUD operation on the server implements each pending record change, with results returned for each operation request in its own network response.
*If the resource supports Submit, the client typically calls saveChanges( ) with a single argument of true. This sends a single Submit operation request across the network for all pending record changes in JSDO memory. Thus, all pending CUD record changes on the server are implemented by this single Submit operation, with all record-change results returned in a single network response.
When the resource supports Submit, the client can instead invoke saveChanges(false) to send CUD operations individually across the network. In this case, the synchronization of record changes works the same as if the resource does not support Submit, as described above.
4. Handles the results from the call to saveChanges( ) using JSDO events or Promises, depending on the availability of Promises and client application requirements.
* Read operation example
* Create operation example
* Update operation example
* Delete operation example
* Submit operation example