home *** CD-ROM | disk | FTP | other *** search
/ The Developer Connection…ice Driver Kit for OS/2 3 / DEV3-D1.ISO / devtools / dataflex / server.pkg < prev    next >
Encoding:
Text File  |  1993-08-10  |  20.6 KB  |  711 lines

  1. //************************************************************************
  2. //
  3. // Copyright 1987-1992 Data Access Corporation, Miami FL, USA
  4. // All Rights reserved
  5. // DataFlex is a registered trademark of Data Access Corporation.
  6. //
  7. //
  8. //     $Source: /u3/source.30/product/pkg/RCS/server.pkg,v $
  9. //     $Revision: 1.1 $
  10. //     $State: Exp $
  11. //     $Author: james $
  12. //     $Date: 1992/09/08 14:43:09 $
  13. //     $Locker:  $
  14. //
  15. //     $Log: server.pkg,v $
  16. //Revision 1.1  1992/09/08  14:43:09  james
  17. //Initial revision
  18. //
  19. //Revision 1.9  92/06/01  14:38:27  steve-l
  20. //changed ADD_WATCHER and REMOVE_WATCHER to ADD_USER_INTERFACE and
  21. //REMOVE_USER_INTERFACE, respectively - "Watcher" distinction no longer
  22. //made by data-sets (but still tracked by DEOs).
  23. //
  24. //Revision 1.8  92/05/14  17:15:59  SWM
  25. //Updated Copyright slug.
  26. //
  27. //Revision 1.7  92/04/07  18:03:21  lee
  28. //added NO_STOP option for broadcasting to override default behavior of
  29. //stopping broadcast on a non-zero return value.
  30. //
  31. //Revision 1.6  92/04/03  18:00:19  lee
  32. //updated add_focus/activate/deactivate/release_focus overrides to use (new)
  33. //return value properly.
  34. //
  35. //Revision 1.5  92/03/29  18:45:15  lee
  36. //added MSG_END_CONSTRUCT_OBJECT, moved ENDMAC macro stuff into END_CONSTRUCT-
  37. //OBJECT procedures (in .pkgs). moved Flag_ITems to list.pkg after generalizing
  38. //it based on PROTOTYPE_OBJECT instead of Whether or not it is a table-oriented
  39. //object. Moved define_access_keys mechanism completely into actionbr.pkg.
  40. //fixed two typos: import_class_protocol used !# instead of !3, and register-
  41. //procedure used !1 instead of !2.
  42. //
  43. //Revision 1.4  92/03/09  19:04:23  james
  44. //Added #CHKSUB directive to insure source
  45. //only compiled with correct revision of 
  46. //compiler.
  47. //
  48. //Revision 1.3  92/01/17  14:25:32  steve-l
  49. //guard isclient=0 added to send UPDATE_DEPENDENT_ITEMS at end of ATTACH_DEO...
  50. //
  51. //Revision 1.2  91/11/08  09:13:08  steve-l
  52. //the procedure ATTACH_DEO_to_SERVER was altered to send the new
  53. //message UPDATE_DEPENDENT_ITEMS as its last action [DAR #1905]
  54. //
  55. //************************************************************************/
  56.  
  57. //************************************************************************
  58. //     File Name: Server.Inc
  59. // Creation Date: January 1, 1991
  60. // Modified Date: January 17, 1992
  61. //     Author(s): Steven A. Lowe
  62. //
  63. // This module defines the operations and properties required to support
  64. // a seperate database 'server' object (as exemplified by Data_Set),
  65. // collected in the abstract class Server_Mixin.
  66. //
  67. // This file should be USEd prior to and IMPORTed within the scope of the
  68. // class definition by any user-interface (esp. data-entry) class which
  69. // must support the data-entry object standards.
  70. //
  71. // This file is used by ENTRYFRM.PKG, TEXT_WIN.PKG, DATALIST.PKG,
  72. // ENCLIENT.PKG, and PICKLIST.PKG.
  73. //************************************************************************/
  74.  
  75.  
  76. //
  77. // Description
  78. //
  79. //   This block defines constants for the spceial find-modes understood by
  80. //   the Request_Find, Request_Read, Request_SuperFind, and Item_Find
  81. //   messages.
  82. //
  83. // Assumptions/Preconditions
  84. //
  85. //   If NEXT_RECORD is already defined as a symbol (i.e. using #REPLACE),
  86. //   it is assumed that FIRST_RECORD and LAST_RECORD are also assigned.
  87. //
  88. // Exceptions
  89. //
  90. //   If NEXT_RECORD is already defined as a symbol, no action is taken.
  91. //
  92. // Notes
  93. //
  94. //   None.
  95. //
  96. #IFSUB 'NEXT_RECORD'
  97. #ELSE
  98.   #REPLACE NEXT_RECORD   5
  99.   #REPLACE FIRST_RECORD  6
  100.   #REPLACE LAST_RECORD   7
  101. #ENDIF
  102.  
  103. #CHKSUB 1 1 // Verify the UI subsystem.
  104.  
  105. use brdcster
  106.  
  107. //
  108. // Description
  109. //
  110. //   These declarations permit forward-referencing of the messages provided
  111. //   by the Data_Set class (in its role as database server).
  112. //
  113. // Assumptions/Preconditions
  114. //
  115. //   None.
  116. //
  117. // Exceptions
  118. //
  119. //   None.
  120. //
  121. // Notes
  122. //
  123. //   None.
  124. //
  125. Register_Procedure Item_Find integer mode integer datafile integer datafield ;
  126.       integer entUpdtFlag integer errFlag integer dfrdFlag
  127. Register_Procedure Add_User_Interface integer obj#
  128. Register_Procedure Remove_User_Interface integer obj#
  129. Register_Procedure Clear
  130. Register_Function  Component_State returns integer
  131. Register_Function  Can_Delete returns integer
  132. Register_Object Element
  133.  
  134.  
  135. class server_mixin is a message
  136.  
  137.   //
  138.   // Description
  139.   //
  140.   //   This procedure defines the properties which are required to support a
  141.   //   server-object for database access.
  142.   //
  143.   // Assumptions/Preconditions
  144.   //
  145.   //   The global function MAKE_BROADCASTER must be defined to return the 
  146.   //   object id of a new instance of the Broadcaster class (see BRDCSTER.PKG).
  147.   //
  148.   // Exceptions
  149.   //
  150.   //   None.
  151.   //
  152.   // Notes
  153.   //
  154.   //   Server is the object id of the database agent for this object.
  155.   //
  156.   //   Watched_Servers is a set of object ids for database agents whose state
  157.   //   must also be monitored by this object (but which never receive requests
  158.   //   directly from this object, unlike the Server).
  159.   //
  160.   //   Servers_Scanned determines if the items of this object have been
  161.   //   scanned to see if this object should be connected to other database
  162.   //   agents as 'just watching' (see Watched_Servers, above).
  163.   //
  164.   //   Auto_Fill_State determines if this object should always automatically
  165.   //   fill itself with data when it is activated.
  166.   //
  167.   //   Deferred_State determines if this object's browsing in database files
  168.   //   should be reflected immediately in this object's database agent (and
  169.   //   the agents' agents, etc.), or not.
  170.   //
  171.   //
  172.   procedure define_server
  173.     local integer obj#
  174.     Property integer private.Server          PUBLIC 0
  175.     Property integer Watched_Servers         PUBLIC 0
  176.     Property integer private.Servers_Scanned PUBLIC 0
  177.     move (make_broadcaster(DESKTOP)) to obj#
  178.     set Watched_Servers to obj#
  179.     set broadcast_state of obj# to TRUE
  180.     Property integer Auto_Fill_State PUBLIC  0
  181.     Property integer Deferred_State  PUBLIC  0
  182.   end_procedure
  183.  
  184.  
  185.   //
  186.   // Description
  187.   //
  188.   //   This procedure establishes a connection between this object and its
  189.   //   database agent(s) (Server and Watched_Servers).
  190.   //
  191.   // Assumptions/Preconditions
  192.   //
  193.   //   This object must understand Client_Area_State; its database agent(s)
  194.   //   must understand Add_User_Interface.
  195.   //
  196.   // Exceptions
  197.   //
  198.   //   If this object has no database agents, no action is taken.
  199.   //
  200.   // Notes
  201.   //
  202.   //   During the establishment of the connection, the database agent(s) may
  203.   //   direct this object to Display or Clear, depending on the state of the
  204.   //   record buffers and Auto_Fill_State.
  205.   //
  206.   procedure attach_deo_to_server
  207.     local integer obj# isclient
  208.     get Server to obj#
  209.     get client_area_state to isclient
  210.     if (obj# <> 0 AND isclient = 0) ;
  211.         send add_user_interface to obj# current_object
  212.     if isclient eq 0 send add_user_interface ;
  213.         to (Watched_Servers(current_object)) current_object
  214.     if (obj# <> 0 AND isclient = 0) send update_dependent_items
  215.   end_procedure
  216.  
  217.  
  218.   //
  219.   // Description
  220.   //
  221.   //   This procedure discontinues the connection between this object and its
  222.   //   database agent(s) (Server and Watched_Servers).
  223.   //
  224.   // Assumptions/Preconditions
  225.   //
  226.   //   This object must understand Client_Area_State; its database agent(s)
  227.   //   must understand Remove_User_Interface.
  228.   //
  229.   // Exceptions
  230.   //
  231.   //   If this object has no database agents, no action is taken.
  232.   //
  233.   // Notes
  234.   //
  235.   //   None.
  236.   //
  237.   procedure remove_deo_from_server
  238.     local integer obj# isclient
  239.     get Server to obj#
  240.     get client_area_state to isclient
  241.     if (obj# <> 0 AND isclient = 0) ;
  242.         send remove_user_interface to obj# current_object
  243.     if isclient eq 0 send remove_user_interface ;
  244.         to (Watched_Servers(current_object)) current_object
  245.   end_procedure
  246.  
  247.  
  248.   //
  249.   // Description
  250.   //
  251.   //   This procedure adds this object into the focus-tree as a child of the
  252.   //   specified toObj#, and also add the child-objects of this object into
  253.   //   the focus-tree as children of this object.  If necessary, it also
  254.   //   scans the fields of this object's items  to determine which database
  255.   //   agents to 'watch', and creates a connection between this object and its
  256.   //   database agents.
  257.   //
  258.   // Assumptions/Preconditions
  259.   //
  260.   //   This object must understand Client_Area_State.
  261.   //
  262.   // Exceptions
  263.   //
  264.   //   None.
  265.   //
  266.   // Notes
  267.   //
  268.   //   Client-objects already automatically add their children into the focus-
  269.   //   tree.
  270.   //
  271.   procedure add_focus integer toObj# returns integer
  272.     local integer srvscn retval
  273.     //
  274.     // standard DEO behavior
  275.     //
  276.     forward get msg_add_focus toObj# to retval
  277.     if retval procedure_return retval
  278.  
  279.     if (client_area_State(current_object) = 0) ; //clients already broadcast
  280.         broadcast NO_STOP send add_focus current_object
  281.     //
  282.     // server augmentation
  283.     //
  284.     get private.Servers_Scanned to srvscn
  285.     if srvscn eq 0 send scan_servers
  286.     if (focus_mode(current_object) <> NO_ACTIVATE AND Active_State(current_object)) ;
  287.         send attach_DEO_to_server
  288.   end_procedure
  289.  
  290.  
  291.   //
  292.   // Description
  293.   //
  294.   //   This procedure removes this object from the focus-tree, and disconnects
  295.   //   it from its database agents, if any.
  296.   //
  297.   // Assumptions/Preconditions
  298.   //
  299.   //   This object must understand Changed_State.
  300.   //
  301.   // Exceptions
  302.   //
  303.   //   If this object has been changed, it will not be detached from its
  304.   //   database agents until the changes are saved or abandoned.
  305.   //
  306.   // Notes
  307.   //
  308.   //   Opposite of Add_Focus.
  309.   //
  310.   procedure remove_object
  311.     forward send remove_object
  312.     if (Changed_State(current_object) = 0) ; //only detach if unchanged!
  313.         send remove_DEO_from_server
  314.   end_procedure
  315.  
  316.  
  317.   //
  318.   // Description
  319.   //
  320.   //   This function returns the object id of the database server which
  321.   //   encloses this object, if any.  Note that only the Data_Set class
  322.   //   defines this function to return anything other than 0.
  323.   //
  324.   // Assumptions/Preconditions
  325.   //
  326.   //   None.
  327.   //
  328.   // Exceptions
  329.   //
  330.   //   None.
  331.   //
  332.   // Notes
  333.   //
  334.   //   This function is used with delegation to locate the Data_Set
  335.   //   which is the closest parent of this object.
  336.   //
  337.   function Find_Server returns integer
  338.   end_function   //returns 0; only Data_Set returns non-zero
  339.  
  340.   Register_Function Server returns integer
  341.  
  342.  
  343.   //
  344.   // Description
  345.   //
  346.   //   This function returns the object id of the database agent of this object,
  347.   //   or 0.
  348.   //
  349.   // Assumptions/Preconditions
  350.   //
  351.   //   None.
  352.   //
  353.   // Exceptions
  354.   //
  355.   //   None.
  356.   //
  357.   // Notes
  358.   //
  359.   //   See the Server function. below.
  360.   //
  361.   function Locate_Server returns integer
  362.     function_return (Server(current_object))
  363.   end_function
  364.  
  365.  
  366.   //
  367.   // Description
  368.   //
  369.   //   This function returns the object id of the database agent of this
  370.   //   object, or 0.
  371.   //
  372.   // Assumptions/Preconditions
  373.   //
  374.   //   This object must understand Component_State.
  375.   //
  376.   // Exceptions
  377.   //
  378.   //   If this object's Server is 0, this object's parent's Server is
  379.   //   returned, if any.
  380.   //
  381.   // Notes
  382.   //
  383.   //   This function is used to allow nested data-entry objects to use the
  384.   //   database agent defined by their parent object.
  385.   //
  386.   function Server returns integer
  387.     local integer obj#
  388.     get private.Server to obj#
  389.     if (obj# = 0 AND Component_State(current_object)) ;
  390.         function_return (Locate_Server(parent(current_object)))
  391.     function_return obj#
  392.   end_function
  393.  
  394.  
  395.   //
  396.   // Description
  397.   //
  398.   //   This procedure sets the value of the Server property of this object,
  399.   //   notifying child-objects of the change, and destroying and creating
  400.   //   connections with database agents, as required.
  401.   //
  402.   // Assumptions/Preconditions
  403.   //
  404.   //   This object must understand Active_State.
  405.   //
  406.   // Exceptions
  407.   //
  408.   //   If the Server of this object is changed while this object is inactive,
  409.   //   no notification of child-objects is required or performed.
  410.   //
  411.   // Notes
  412.   //
  413.   //   None.
  414.   //
  415.   procedure set Server integer newVal
  416.     local integer oldVal
  417.     get Server to oldVal
  418.     if newVal ne 0 set private.Server to (object_id(newVal))
  419.     else set private.Server to newVal
  420.     if (active_state(current_object)) begin
  421.       broadcast send server_changed oldVal newVal
  422.       if oldVal ne 0 send remove_deo_from_server  //detach from current server
  423.       if newval ne 0 send attach_deo_to_server    //attach to new server
  424.     end
  425.   end_procedure
  426.  
  427.  
  428.   //
  429.   // Description
  430.   //
  431.   //   This procedure servers as notification of a change in the connection
  432.   //   of this object's parent to its database agent.  If this object uses
  433.   //   its parent's database agent by default (see the Server and Find_Server
  434.   //   functions, above), it must disconnect from the old agent and connect
  435.   //   with the new agent.
  436.   //
  437.   // Assumptions/Preconditions
  438.   //
  439.   //   This object must understand Client_Area_State.
  440.   //
  441.   // Exceptions
  442.   //
  443.   //   None.
  444.   //
  445.   // Notes
  446.   //
  447.   //   None.
  448.   //
  449.   procedure server_changed integer oldVal integer newVal
  450.     local integer oldSrvr
  451.     if (client_area_state(current_object) = 0) begin
  452.       get private.Server to oldSrvr
  453.       if (oldSrvr = 0) begin  //assumes Server(current_object) = oldVal by deleg
  454.         if oldVal ne 0 send remove_user_interface to oldVal current_object
  455.         if newVal ne 0 send add_user_interface to newVal current_object
  456.       end
  457.     end
  458.   end_procedure
  459.  
  460.  
  461.   //
  462.   // Description
  463.   //
  464.   //   This procedure empties the Watched_Servers broadcaster, after
  465.   //   detaching this object from all of the broadcaster's elements.
  466.   //
  467.   // Assumptions/Preconditions
  468.   //
  469.   //   None.
  470.   //
  471.   // Exceptions
  472.   //
  473.   //   None.
  474.   //
  475.   // Notes
  476.   //
  477.   //   This procedure is invoked by Find_Servers_to_Watch, in preparation
  478.   //   for a scan.
  479.   //
  480.   procedure delete_watched_servers
  481.     local integer vis#
  482.     get watched_servers to vis#
  483.     send Remove_User_Interface to vis# current_object  //detach from all
  484.     set broadcast_state of vis# to false
  485.     send delete_Data to vis#                    //empty it
  486.     set broadcast_state of vis# to true
  487.   end_procedure
  488.  
  489.  
  490.   //
  491.   // Description
  492.   //
  493.   //   This procedure adds the specified object id (obj#) to this object's
  494.   //   set of database agents who are merely 'watched', and establishes a
  495.   //   connection between the database agent and this object.
  496.   //
  497.   // Assumptions/Preconditions
  498.   //
  499.   //   This object must understand Active_State.
  500.   //
  501.   // Exceptions
  502.   //
  503.   //   None.
  504.   //
  505.   // Notes
  506.   //
  507.   //   None.
  508.   //
  509.   procedure add_watched_server integer obj#
  510.     local integer vis# ndx
  511.     get watched_servers to vis#
  512.     set broadcast_state of vis# to false
  513.     get find_element of vis# obj# to ndx
  514.     if ndx lt 0 send add_element to vis# obj#
  515.     set broadcast_state of vis# to true
  516.     if (ndx lt 0 AND active_State(current_object)) ;
  517.       send add_user_interface to obj# current_object
  518.   end_procedure
  519.  
  520.  
  521.   //
  522.   // Description
  523.   //
  524.   //   This procedure removes the specified object id (obj#) from this object's
  525.   //   set of database agents who are merely 'watched', and destroys the
  526.   //   connection between the database agent and this object.
  527.   //
  528.   // Assumptions/Preconditions
  529.   //
  530.   //   This object must understand Active_State.
  531.   //
  532.   // Exceptions
  533.   //
  534.   //   None.
  535.   //
  536.   // Notes
  537.   //
  538.   //   None.
  539.   //
  540.   procedure remove_watched_server integer obj#
  541.     local integer vis# ndx
  542.     get watched_servers to vis#
  543.     set broadcast_state of vis# to false
  544.     get find_element of vis# obj# to ndx
  545.     if ndx ge 0 send remove_element to vis# obj#
  546.     set broadcast_state of vis# to true
  547.     if (ndx >= 0 AND active_State(current_object)) ;
  548.         send remove_user_interface to obj# current_object
  549.   end_procedure
  550.  
  551.  
  552.   //
  553.   // Description
  554.   //
  555.   //   This procedure causes the scanning of this object's items' fields,
  556.   //   and the production of a set of database agents who should be 'watched'.
  557.   //
  558.   // Assumptions/Preconditions
  559.   //
  560.   //   None.
  561.   //
  562.   // Exceptions
  563.   //
  564.   //   None.
  565.   //
  566.   // Notes
  567.   //
  568.   //   This procedure depends completely upon Find_Servers_To_Watch, below.
  569.   //
  570.   procedure Scan_Servers
  571.     send find_servers_to_watch FALSE
  572.   end_procedure
  573.  
  574.  
  575.   //
  576.   // Description
  577.   //
  578.   //   This procedure scans the fields of this object's items to determine
  579.   //   what other database agents (data_sets) other than this object's Server
  580.   //   should be 'watched' (for data changes).
  581.   //
  582.   // Assumptions/Preconditions
  583.   //
  584.   //   tableFlag is a boolean determining whether this object relies on a
  585.   //   prototype row (TRUE) or an item list (FALSE).
  586.   //
  587.   //   This object must understand Client_Area_State, and have a private
  588.   //   boolean property named Private.Servers_Scanned to note the event.
  589.   //
  590.   // Exceptions
  591.   //
  592.   //   None.
  593.   //
  594.   // Notes
  595.   //
  596.   //   This procedure is invoked once per object, the first time the object
  597.   //   is activated.  If the data_file, data_field, and/or main_file of this
  598.   //   object are changed (don't change them while this object is active!),
  599.   //   set Private.Servers_Scanned to FALSE to force this object to scan
  600.   //   again (when it is next activated).
  601.   //
  602.   procedure find_servers_to_watch integer tableFlag
  603.     local integer i file# obj# maxitems count p srvr# self#
  604.     local string fileStr fStr
  605.     set private.Servers_Scanned to TRUE
  606.     if tableFlag ne 0 get Prototype_Object to self#
  607.     else move current_object to self#
  608.     get Server to srvr#
  609.     if (srvr# <> 0 AND client_area_state(current_object) = 0) begin
  610.       move "," to fileStr
  611.       if tableFlag ne 0 begin
  612.         get main_file to i
  613.         append fileStr i ","   //insert mainfile to be sure it's watched
  614.       end
  615.       move 0 to count
  616.       get item_count of self# to maxitems
  617.       for i from 0 to (maxitems - 1)
  618.         get data_file of self# item i to file#
  619.         if (file# > 0 AND not(fileStr contains (","+string(file#)+","))) begin
  620.           move (fileStr+string(file#) + ",") to fileStr
  621.           increment count
  622.         end
  623.       loop
  624.       right fileStr to fileStr (length(fileStr) - 1)  //remove leading comma
  625.       send delete_watched_servers  //empty Watched_Servers broadcaster first
  626.       for i from 0 to count
  627.         pos "," in fileStr to p
  628.         if p gt 1 begin
  629.           left fileStr to fStr (p-1)
  630.           right fileStr to fileStr (length(fileStr) - p)
  631.           move fStr to file#
  632.           get which_data_set of srvr# file# to obj#
  633.           if (obj# <> 0 AND obj# <> srvr#) send add_Watched_server obj#
  634.         end
  635.       loop
  636.     end
  637.   end_procedure
  638.  
  639.   //
  640.   // created for Nesting support
  641.   //
  642.   procedure Mark_As_Component
  643.     local integer ser#
  644.     set Component_State to true
  645.     delegate set Has_Components_State to true
  646.     get private.Server to ser#
  647.     if ser# eq 0 begin
  648.       delegate get Locate_Server to ser#
  649.       if ser# ne 0 set private.Server to ser#
  650.     end
  651.   end_procedure
  652.  
  653.   procedure SET Changed_State integer newVal
  654.     local integer srvr#
  655.     forward set Changed_State to newVal
  656.     get server to srvr#
  657.     if (newVal AND srvr#) set Changed_State of srvr# to TRUE
  658.     if (newVal) set Changed_State of (Watched_Servers(current_object)) to TRUE
  659.     if (not(newVal) AND not(Active_State(current_object))) ;
  660.       send remove_DEO_from_Server
  661.   end_procedure
  662.  
  663.   function validate_items integer flag returns integer
  664.     local integer retval oldautotop
  665.     forward get validate_items flag to retval
  666.     if (retval <> 0 AND focus(desktop) <> current_object) begin
  667.       get auto_top_item_state to oldautotop
  668.       set auto_top_item_state to false
  669.       send activate  //take focus w/out changing current_item
  670.       set auto_top_item_state to oldautotop
  671.     end
  672.     function_return retval
  673.   end_function
  674.  
  675. end_class
  676.  
  677.  
  678. //
  679. // Description
  680. //
  681. //   This macro processes the optional USING argument on an object-creation
  682. //   command line, by setting the Server of this object as appropriate.
  683. //
  684. // Assumptions/Preconditions
  685. //
  686. //   None.
  687. //
  688. // Exceptions
  689. //
  690. //   If the USING option does not appear on the command line, no action is
  691. //   taken.
  692. //
  693. // Notes
  694. //
  695. //   None.
  696. //
  697. #COMMAND bind_using
  698.   #IF (!0>0)
  699.     #IFSAME !1 USING
  700.       #IFDEF !2
  701.         set Server to !2
  702.       #ELSE
  703.         set Server to !2.obj
  704.       #ENDIF
  705.     #ELSE
  706.       bind_using !2 !3 !4 !5 !6 !7 !8 !9
  707.     #ENDIF
  708.   #ENDIF
  709. #ENDCOMMAND
  710.                                                                                                                 
  711.