Dynamic Temp-table On Appserver

emnu

Member
Hi,

In an appserver session I create a dynamic temp-table, which is returned as TABLE-HANDLE output parameter to the calling procedure. The goal is to fill a local dynamic temp-table with the records of the TABLE-HANDLE of the output parameter. I don't now which table will be returned by the called appserver procedure, so i create this local temp-table dynamicly, the information on which table the output is based is stored in the second parameter, next code in the calling proc (clientside) illustrates this:

/* Return a filled temp-table in appserver session, which table is
not known */

IF VALID-HANDLE(hProc) THEN
RUN prcFillTT IN hProc
(OUTPUT TABLE-HANDLE hSrvRowObject,
).

My Question is, how can i dynamically create a temp-table in my local client session, based on the OUTPUT TABLE-HANDLE returned from the server ?
Or is there any other solution for this ?

Thanx for any Reponse,

Emmanuel.
 

jongpau

Member
Hi Emmanuel,

You do not have to create the temp-table on your client, Progress does that for you when you pass the table-handle parameter.

You can access the temp-table by using it's buffer-handle and dynamic queries. For instance:
Code:
DEF VAR hTempBuffer AS HANDLE NO-UNDO.
DEF VAR hQuery      AS HANDLE NO-UNDO.

IF VALID-HANDLE(hProc) 
THEN RUN prcFillTT IN hProc (OUTPUT TABLE-HANDLE hSrvRowObject).
IF VALID-HANDLE(hSrvRowObject)
THEN hTempBuffer = hSrvRowObject: DEFAULT-BUFFER-HANDLE.

CREATE QUERY hQuery.
hQuery:ADD-BUFFER(hTempBuffer).
hQuery:QUERY-PREPARE("FOR EACH ":U + hTempBuffer:NAME).
hQuery:QUERY-OPEN.
..
..
The Dynamic temp table (and it's contents) are available on your client until you destroy the temp-table (delete object). So it's only a question of "remembering" the table and/or buffer handle of the temp-table. If you create the temp-table on the AppServer and give it the same (or similar) definitions to the database table and give it the same name, you should not even have to send back the other information you are talking about, because you can retrieve all the information through the attributes of the table handle and buffer handle of the temp-table (see Progress doc and/or help).

Note: Do NOT forget to delete all the dynamic objects once you do not need them anymore or when your procedure finishes. Otherwise you will create a "memory leak".

HTH
 

emnu

Member
Hi Paul,

That's true, Progress indeed sends table definition & table-data along with teh TABLE-HANDLE , the records can be viewed by accessing the default-bufer-handle and creating a query on it, i implemented these features already in my application before, and these work fine indeed.

But my goal is to do it the SDO (SmartDataObjects) way, namely a first batch of records are returned form appserver (lets say with a max-guess of 50), these are available on the table-handle.
There should be a second internal dynamic table to hold these records from the table-handle.

Than a second batch of 50 recs are returned from the server, so the hSrvRowObject TABLE-HANDLE returns the next 50, and those are appended to the local created dynamic temp-table
So, this table will now be loaded with 100 records (2 batches of 50 recs returned from TABLE-HNADLE hSrvRowObject.
We don't know beforehand which table will be returned, so this one must be the same as the hSrvRowobject table.

To illustrate this i'll show the AppServer procedure i made, which fills the table, and the client procedure, which copy the records batches from the server table-handle to the local temp-table:


/* APPSERVER PROCEDURE BEGINS */

DEF OUTPUT PARAM TABLE-HANDLE hSrvRowObject.
DEF OUTPUT PARAM cTableName AS CHAR NO-UNDO.

DEF VAR ttHandle AS HANDLE NO-UNDO.

DEF VAR bhTT AS HANDLE NO-UNDO.
DEF VAR bhQry AS HANDLE NO-UNDO.
DEF VAR qhQry AS HANDLE NO-UNDO.

DEF VAR fh AS HANDLE EXTENT 2 NO-UNDO.
DEF VAR i AS INT NO-UNDO.
DEF VAR cQueryString AS CHAR NO-UNDO.

/* create tt */
CREATE TEMP-TABLE ttHandle.
ttHandle:CREATE-LIKE("department").
ttHandle:TEMP-TABLE-PREPARE("ttTable":U).
bhTT = ttHandle:DEFAULT-BUFFER-HANDLE.



/* create buffer handle for query */
CREATE BUFFER bhQry FOR TABLE "customer".

/* set fields for buffer handle for query */
DO i = 1 TO NUM-ENTRIES("custnum,name"):
fh = bhQry:BUFFER-FIELD(ENTRY(i,"custnum,name")).
END.

/* create the query */
CREATE QUERY qhQry.

/* set buffers voor query */
qhQry:SET-BUFFERS(bhQry).

ASSIGN cQueryString = "for each " + bhQry:NAME.

qhQry:QUERY-PREPARE(cQueryString) NO-ERROR.

qhQry:QUERY-OPEN.
qhqry:GET-FIRST(NO-LOCK).

/* fill the tt */

lus:
REPEAT :
IF qhQry:QUERY-OFF-END THEN LEAVE lus.
bhTT:BUFFER-CREATE().
bhTT:BUFFER-COPY(bhQry).
bhTT:BUFFER-RELEASE().
qhQry:GET-NEXT(NO-LOCK).
END.

ASSIGN
hSrvRowObject = ttHandle
cTableName = bhQry:TABLE.

/* APPSERVER PROCEDURE ENDS */

/* CLIENT PROCEDURE BEGINS */

/* Initial load of temp-table with 50 customer recs */
IF VALID-HANDLE(hProc) THEN
RUN prcFillTT IN hProc (INPUT "customer":U, INPUT 50,
OUTPUT TABLE-HANDLE hSrvRowObject, OUTPUT cTableName).

/* Set default buffer-handle for the table-handle */
bhSrvRowObject = hSrvRowObject:DEFAULT-BUFFER-HANDLE.

/* create local temp-table for holding next batches of customer
records */
CREATE TEMP-TABLE hLocalRowObject.

/* THIS DOESNT WORK */
hLocalRowObject:CREATE-LIKE(hSrvRowObject).
hLocalRowObject:TEMP-TABLE-PREPARE("ttTable":U).
bhLocalRowObject = hLocalRowObject:DEFAULT-BUFFER-
HANDLE.

/* Create query for server Rowobject to copy records */
CREATE QUERY qh.
qh:SET-BUFFERS(bhSrvRowObject).
qh:QUERY-PREPARE("for each ttTable").
qh:QUERY-OPEN.

/* Buffer-copy those rec's from ServerRowObject TT to
LocalRowObject TT */
BUFFER-COPY-BLOCK:
REPEAT :
IF qh:QUERY-OFF-END THEN LEAVE BUFFER-COPY-BLOCK.
bhLocalRowObject:BUFFER-CREATE().
bhLocalRowObject:BUFFER-COPY(bhSrvRowObject).
bhLocalRowObject:BUFFER-RELEASE().
qh:GET-NEXT(NO-LOCK).
END.

/* CLIENT PROCEDURE ENDS */


Thanx for any response,

Emmanuel.
 

jongpau

Member
HI Emmanuel,

I think you have to use the buffer-handle with CREATE-LIKE instead of the table-handle so:
hLocalRowObject:CREATE-LIKE(bhSrvRowObject).

Give that a try... (without looking at my own code) I am pretty sure it should work....

HTH
 
Top