Consultor Eletrônico



Kbase P17009: Roundtable. Managing Data for Dynamic widgets
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   15/10/2008
Status: Unverified

GOAL:

Roundtable. Managing Data for Dynamic widgets

FIX:

Summary


One of the primary purposes of the custom edit program is to manage data that is used to build dynamic widgets - such as a menu.  Roundtable is able to manage this data, automating its replication through your workspaces and ultimately to the customer. You must create a custom edit program tailored to your environment in order to facilitate this automation. This type of initial Roundtable setup is typically performed by an expert consultant hired to implement Roundtable.  If you are not managing data in tables to use with table driven widgets or screen layouts, you do not need to read this white paper.


Custom Edit Program


4GL objects, such as a menu or a screen layout, may be built dynamically based on information from a table. When this data is changed in development, it must also be changed in QA, testing, and at the customer's site. Roundtable manages this data though the use of the custom-edit program. The custom edit program is used to delete the table data, to create the text file from new table data (dump the data), and to populate tables with existing data in a text file (load data).   

You define a Roundtable ?SUBTYPE? for the text files that will be used to hold dumped data. This subtype will specify the correct ?Custom Edit Program?  (see the Roundtable User's Guide for more information on how to define the custom edit program for a subtype in Roundtable). The custom edit program is simply a Progress procedure designed to manage your data. Roundtable calls the custom edit program and passes it the following values in the ?Pmode? input parameter:

View - Passed to the custom edit program when you view an object read-only. The edit program should call the program used to view the object (e.g. a text editor in read-only mode).

Edit - Passed to the custom edit program when you open an object for edit.  The edit program should call the Progress program used to edit the object (e.g. a text editor).

Import - Passed to the custom edit program at a point after an object is imported or newly assigned into a workspace (see note 1). The edit program should call a Progress program that reads the data from the text file and populates the database table (a Progress Import or Load). You more than likely would want to delete the old data first.

Export - Passed to the custom edit program during the check-in process. The edit program should call a Progress program that writes out the data from the table to the text file (a Progress export or dump).

Delete - Passed to the custom edit program when an object is deleted (removed) from the workspace. The edit program should call a Progress program that deletes the data in the table.


Note:

1. Use the "Workspace->All PCODE data imports" utility in Roundtable after you import or assign objects into a workspace. It runs all custom edit programs in import mode so that your database is re-populated with the most current data from the newly imported or assigned text files.
Simply importing or assigning an object to a workspace only flags the object for import mode.  Roundtable will not run the custom edit program in import mode until you open the object or you run "ALL PCODE Data Imports".


Example


?P-dymenu.p? is supplied in source in your Progress 4GL installation directory (see appendix A for source).  It is an example program using data from the sports database to dynamically build a menu. When the data changes in the SALESREP table, the menu changes. In most scenarios, developers need a way to track this data so that the correct menu choices are moved and tested in QA and then deployed to the customer.

Although ?p-dymenu.p? is not a ?real-life? example of data that must be moved forward, it is sufficient to demonstrate the process.


To support the data needed to populate this m.enu, you must:
1. Define a subtype called "datafile", specifying a subtype edit program of ?util/cust_editp.p?.  
2. Create an object in the "util" module, to serve as the custom edit program, called "cust_editp.p" (using a normal program subtype).
3. Create a new object called "salesrep.d" in the "data" module using the newly created "datafile" subtype.


rtb_editp.p:


The following is the source for my custom edit program, cust_editp.p:

/* cust_editp.p  
  Gerry Winning
  
  Example custom edit program for managing application data. This edit program
  assumes that all .d files associated with this edit program are for the same
  database that is named sports.

*/


/* --- Define parameters --- */
DEFINE INPUT  PARAMETER Pmode            AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER Perror           AS CHARACTER NO-UNDO.


/* --- Define shared --- */
DEFINE SHARED VARIABLE Urtb-object     AS CHARACTER           NO-UNDO.
DEFINE SHARED VARIABLE Urtb-part       AS CHARACTER EXTENT 10 NO-UNDO.
DEFINE SHARED VARIABLE Urtb-part-desc  AS CHARACTER EXTENT 10 NO-UNDO.
DEFINE SHARED VARIABLE Urtb-path       AS CHARACTER EXTENT 10 NO-UNDO.
DEFINE SHARED VARIABLE Urtb-name       AS CHARACTER EXTENT 10 NO-UNDO.
DEFINE SHARED VARIABLE Urtb-tmpl       AS CHARACTER EXTENT 10 NO-UNDO.
DEFINE SHARED VARIABLE Urtb-num-parts  AS INTEGER             NO-UNDO.
DEFINE SHARED VARIABLE Urtb-sub-type   AS CHARACTER           NO-UNDO.
DEFINE SHARED VARIABLE Urtb-userid     AS CHARACTER           NO-UNDO.
DEFINE SHARED VARIABLE Urtb-task-num   AS INTEGER             NO-UNDO.
DEFINE SHARED VARIABLE Urtb-task-desc  AS CHARACTER           NO-UNDO.
DEFINE SHARED VARIABLE Urtb-propath    AS CHARACTER           NO-UNDO.
DEFINE SHARED VARIABLE Urtb-ws-propath AS CHARACTER           NO-UNDO.
DEFINE SHARED VARIABLE Urtb-mod-dir    AS CHARACTER           NO-UNDO.

DEFINE VARIABLE Mfile   AS CHARACTER    NO-UNDO.
DEFINE VARIABLE Mtable  AS CHARACTER    NO-UNDO.



MESSAGE PMODE "SS".
ASSIGN Mfile  = Urtb-path[1].

CASE Pmode:
 WHEN "edit" OR WHEN "view" THEN
   RUN edit_view_mode.
 WHEN "import" THEN
   RUN import_mode.  /* Data will be read into the DB from the table */
 WHEN "export" THEN
   RUN export_mode.  /* Text file is updated with data form the table */
 WHEN "delete" THEN
   RUN delete_mode.  /* Data is removed from the table */
END.  

/*.........................internal procedures..........................*/

/* ------------------  edit and view mode  ----------------------*/

PROCEDURE edit_view_mode:
/* Use the Progress Procedure Editor to edit the text file. This gives
  us the benefits of Roundtables standard intercepts into the Progress
  ADE hooks.
*/

RUN adecomm/_pwmain.p
       ( INPUT  "Roundtable" ,
         INPUT  Mfile,
         INPUT  "" ).  

END PROCEDURE.

/* ------------------  import mode  ----------------------*/

PROCEDURE import_mode:

 /* clean our the table first */
 RUN delete_mode.
 DISABLE TRIGGERS FOR LOAD OF customer.

 INPUT FROM VALUE(Mfile).  /* Mfile is the name and path to salesrep.d */
   
 /* You could use positional parameters for another.p or a dynamic
    query here building the table name from the file name, but I'll
    keep it in IF statements for example purposes */
 
 IF Urtb-object = "salesrep.d" THEN DO:
   REPEAT:
     CREATE sports.salesrep.
     IMPORT sports.salesrep.
   END.
 END.
    
 INPUT CLOSE.

END PROCEDURE.

/* ------------------  export mode  ----------------------*/

PROCEDURE export_mode:
 DISABLE TRIGGERS FO.R DUMP OF customer.

 OUTPUT TO VALUE(Mfile). /* Mfile is the name and path to salesrep.d */
 
 /* You could use positional parameters for another.p or a dynamic
    query here building the table name from the file name, but I'll
    keep it in IF statements for example purposes */
 
 IF Urtb-object = "salesrep.d" THEN DO:
   FOR EACH sports.salesrep:
     EXPORT sports.salesrep.
   END.
 END. /* if Urtb-object = salesrep */
 OUTPUT CLOSE.

END PROCEDURE.

/* ------------------  delete mode  ----------------------*/

PROCEDURE delete_mode:

 /* You could use positional parameters for another.p or a dynamic
    query here building the table name from the file name, but I'll
    keep it in IF statements for example purposes */

 IF Urtb-object = "salesrep.d" THEN DO:
   FOR EACH sports.salesrep:
     DELETE sports.salesrep VALIDATE(TRUE,"").
   END.
 END. /* if urtb-object = salesrep.d */
 
END PROCEDURE.


Salesrep.d:

When I check in "salesrep.d", the custom edit program is run in export mode and automatically writes out the new data from the table into the text
file just before ?salesrep.d? is checked in.  Using the data provided with the sports database, you would see the following in the ?salesrep.d? file
after checking it in:

"BBB" "Brawn , Bubba B." "East" 1600 1648 1697 1748 1800 1854 1910 1967 2026 2087 2150
"DKP" "Pitt , Dirk K." "Central" 1800 1854 1910 1967 2026 2087 2150 2215 2281 2349 2419
"DOS" "Donna Swindall" "Southern" 3800 3914 4031 4152 4277 4405 4537 4673 4813 4957 5106
"GPE" "Gilles Ehrer" "Bretagne" 1600 1648 1697 1748 1800 1854 1910 1967 2026 2087 2150
"HXM" "Harry Munvig" "Sverige" 3800 3914 4031 4152 4277 4405 4537 4673 4813 4957 5106
"JAL" "Jan Loopsnel" "Noord" 2200 2266 2334 2404 2476 2550 2627 2706 2787 2871 2957 3046
"KIK" "Kari Iso-Kauppinen" "Finland" 1800 1854 1910 1967 2026 2087 2150 2215 2281 2349
"RDR" "Robert Roller" "Austria" 4200 4326 4456 4590 4728 4870 5016 5166 5321 5481 5645
"SLS" "Smith , Spike Louise" "West" 3000 3090 3183 3278 3376 3477 3581 3688 3799 3913


The End Result


After importing the schema into the next workspace and performing a "schema update" to build the physical database, you end up with copy of the database with no data.   The import process flags all PCODE objects that have a custom edit program to be run in ?import mode? (including "salesrep.d?). Running  the "ALL PCODE Data Imports" utility would fire off all custom edit programs in "import" mode.  When ?cust_editp.p? is run in ?import? mode, it will import all the data from "salesrep.d" into the ?SALESREP? database table.


The Deployment


If you deploy your application to customers, the same "salesrep.d" file is packaged with your deployment. To automate the delete and load of the new data into the customer's database , you can create data procedures.(see the Roundtable User's Guide for information on using data procedures) or modify the ?schupd.p? and ?schupdp2? procedures created by the Roundtable deployment process.  


Note:


If you choose to modify schupdp2.p yourself, make sure you check it into a module with a directory of ?rtb_inst?. When you create a deployment, Roundtable will automatically generate the generic ?rtb_inst/schupdp2.p? off of the root deployment directory, then will deploy your customized copy of ?rtb_inst/schupdp2.p? on top of it.


Appendix

Appendix A


/* p-dymenu.p */

DEFINE VARIABLE exit-item-ptr    AS WIDGET-HANDLE.
DEFINE VARIABLE srep-menu-ptr AS WIDGET-HANDLE.
DEFINE VARIABLE main-bar-ptr  AS WIDGET-HANDLE.
DEFINE VARIABLE temp-hand-ptr AS WIDGET-HANDLE.

FORM
  salesrep.sales-rep rep-name salesrep.region month.-quota
  WITH FRAME x WITH SIDE-LABELS ROW 5 CENTERED.

VIEW FRAME x.

/* Create the main menu bar. */
CREATE MENU main-bar-ptr.
    
/* Create a pull-down menu to list all sales reps. */
CREATE SUB-MENU srep-menu-ptr
    ASSIGN PARENT = main-bar-ptr
          LABEL = "Reps".

/* Create a menu item for each record in the Salesrep file. */             
FOR EACH Salesrep BY rep-name:
  CREATE MENU-ITEM temp-hand-ptr
      ASSIGN PARENT = srep-menu-ptr
             LABEL = salesrep.rep-name
      TRIGGERS:
          ON CHOOSE
             DO:
                FIND FIRST salesrep WHERE rep-name = SELF:LABEL.
                DISPLAY salesrep WITH FRAME x.
             END.
      END TRIGGERS.
END.

/* Add a rule to the srep-menu-ptr. */
CREATE MENU-ITEM temp-hand-ptr
    ASSIGN SUBTYPE = "RULE"
          PARENT = srep-menu-ptr.

/* Add an exit item to the srep-menu-ptr. */
CREATE MENU-ITEM exit-item-ptr
   ASSIGN PARENT = srep-menu-ptr
         LABEL = "E&xit"
         SENSITIVE = TRUE.
         

/* Set up the menu bar. */
CURRENT-WINDOW:MENUBAR = main-bar-ptr.

/* Disable menu items for all west coast sales reps.
  To begin, find the first item in srep-men-ptr.        */
temp-hand-ptr = srep-menu-ptr:FIRST-CHILD.

test-items:
DO WHILE temp-hand-ptr <> ?:
  /* Find the Salesrep record for this item (if any). */
  IF temp-hand-ptr:SUBTYPE = "NORMAL"
  THEN DO:
      FIND FIRST salesrep WHERE salesrep.rep-name =
                                temp-hand-ptr:LABEL NO-ER~
ROR.
  
     /* Check if this rep is in the West region.
       If so, disable the menu item.             */
     IF AVAILABLE(salesrep)
     THEN IF salesrep.region = "West"
         THEN temp-hand-ptr:SENSITIVE = FALSE.
  END.
  
  /* Find the next item in srep-men. */
  temp-hand-ptr = temp-hand-ptr:NEXT-SIBLING.
END.

/* Wait for the user to select Exit. */
WAIT-FOR CHOOSE OF exit-item-ptr.
/* end program */.