Try OpenEdge Now
skip to main content
ProDataSets
Advanced Read Operations : Caching data using a ProDataSet : Using a subset of the tables in a ProDataSet : Writing the server procedure
 
Writing the server procedure
You already know how to return an entire ProDataSet to another procedure. You also know how to deactivate relations or designate tables as NO-FILL. When you do this you return some tables as empty to the caller. Let us look at how you could return a dynamic ProDataSet that represents a subset of the tables that are defined in a larger one. In the case of the code table ProDataSet, some callers might not want all the tables at all, or might not even know of their existence or have any definitions to receive them into. In this case the server can dynamically subset the data at the table level according to the caller's request.
Let us write that server procedure now. As with other examples, the code is simplified to the extent that it runs in a single session, but the backend server procedures are clearly separated from the user interface procedures that run on the client.
To update the code:
1. Create the new procedure called CodeSupport.p, as shown in the following code block.
It first includes the temp-table and ProDataSet definitions. The definitions, of course, also create an instance of that static ProDataSet and its temp-tables when CodeSupport.p is run. This means that in effect each run-time instance of CodeSupport.p "owns" its own instance of the ProDataSet as well. This allows any internal procedures to use static ABL to reference the ProDataSet and its data, as well as any other procedures to which the ProDataSet might be passed by reference. This is different from how CodeSource.p operates. Because it has no static definition and receives only the ProDataSet handle as input, it operates only on an instance of the ProDataSet actually created and managed elsewhere (namely here in CodeSupport.p).
CodeSupport.p starts an instance of CodeSource.p and then requests it to attach the Data-Sources using the attachDataSet function and fills the ProDataSet, as shown:
/* CodeSupport.p -- support procedures for dsCode tables */
{dsCodeTT.i}
{dsCode.i}

DEFINE VARIABLE hCodeSet AS HANDLE  NO-UNDO.
DEFINE VARIABLE hCodeSource AS HANDLE  NO-UNDO.
DEFINE VARIABLE hSourceProc AS HANDLE  NO-UNDO.
DEFINE VARIABLE lError      AS LOGICAL NO-UNDO.

hCodeSet = DATASET dsCode:HANDLE.
RUN CodeSource.p PERSISTENT SET hSourceProc.
lError = DYNAMIC-FUNCTION("attachDataSet" IN hSourceProc, hCodeSet).
hCodeSet:FILL().
2. Next, create the internal procedure that actually generates a new ProDataSet with a subset of the tables in the original one, fetchCodeTables, as shown:
PROCEDURE fetchCodeTables:
  DEFINE INPUT PARAMETER pcTables AS CHARACTER NO-UNDO.
  DEFINE OUTPUT PARAMETER DATASET-HANDLE phDynData.

  DEFINE VARIABLE cTable AS CHARACTER NO-UNDO.
  DEFINE VARIABLE hTableBuf AS HANDLE    NO-UNDO.
  DEFINE VARIABLE iTable AS INTEGER   NO-UNDO.

  CREATE DATASET phDynData.
  DO iTable = 1 TO NUM-ENTRIES(pcTables):
    cTable = ENTRY(iTable,pcTables).
    CREATE BUFFER hTableBuf FOR TABLE cTable.
    phDynData:ADD-BUFFER(hTableBuf).
  END.
END PROCEDURE. /* fetchCodeTables */
This takes a table list as input, creates a new dynamic ProDataSet along with new buffers for the static ProDataSet's tables, and adds the buffers to the ProDataSet. This makes the existing data (already retrieved and filled) in the ProDataSet dsCode part of the new ProDataSet without any need to copy it, because the caller wants all the data in the requested subset of the tables.
Since you are putting the same static temp-tables into the new ProDataSet, why do you need new dynamic buffers for them? Remember that there is a rule that a temp-table can be part of more than one ProDataSet at a time, but one temp-table buffer can only be part of one ProDataSet at a time. The AVM generally manages the temp-tables in a ProDataSet through their buffers, and it can do this only when each ProDataSet has its own distinct set of buffers, even when temp-tables are shared. If you were to leave out the CREATE BUFFER statement, you could try to add the existing static buffer from dsCode directly into the new ProDataSet, as shown:
/* You cannot use the same buffer in two ProDataSets: */
phDynData:ADD-BUFFER(DATASET dsCode:GET-BUFFER-HANDLE(iTable)).
If you did, you would get the following error when you run an application that uses fetchCodeTables: