ARRAYS xpg treats attributes of array types different than other types. When you double-click on the name of an array-type attribute, it is not selected to be key attribute (or deselected) as with other types; instead it opens the Array Dialog for this attribute. While the Array Dialog is opened, selecting a tuple makes the Array Dialog view (in its list) the array elements of the currently selected attribute and the currently selected tuple (ie., the array elements of the intersection of the tuple and the attribute which is monitored by the Array Dialog). The Array Dialog's purpose is to allow the user to execute external user-defined commands which are based on values taken from the relation. The Array Dialog can have up to three such commands. After an attribute and a tuple have been selected, the user can select one of the array elements appearing in the Array Dialog, and execute any of the three commands, passing it the selected element, as described below. Whenever a new tuple is selected, the Array Dialog updates to show the elements of the new tuple. When a new attribute (of array type) is double-clicked, the Array Dialog's list is cleared and you must select a tuple for the dialog to show its elements. For each of the three commands, three resources are defined: - arrayCmd[1-3] the external command to execute - arrayCmdPath[1-3] path for files - arrayCmdName[1-3] the label appearing on the command's button These resources are described in more detail in the XPG RESOURCES section. xpg provides two method for passing data to external commands: - Passing a string The selected array element is passed to the external command, which does the rest. In order to use this method, include the string "%%" (without the quotes) in your arrayCmd resource. This string (or whatever string defined in xpg.h as VAL_PHOLDER) is replaced by the array element value, and then the command is passed to sh(1) for execution, from the directory specified in arrayCmdPath (ie. xpg chdir's to arrayCmdPath before executing arrayCmd). This method is the default method for executing external commands. - Passing the data The selected array element is treated as a key to the Inversion tool (found in the Postgres' examples). The data is extracted from the appropriate class, using Inversion, and piped (using popen(3)) into arrayCmd. the resource arrayCmdPath is ignored when this method is used. To use this method rather than the previous (default) method, put a pipe ('|') character before the command name in the arrayCmd resource. Note: this method was included in xpg because it was already implemented, and not because it is better in any way than the first one. I recommend you to use the default method unless you want to experiment with Inversion and large objects. In both methods xpg forks a child to run the external command. xpg does not attempt to monitor or control the child process in any way. An example use of the Array Dialog and the array commands is for viewing pictures. As a matter of fact, this example was the reason for developing this mechanism; it was first implemented using the Inversion tool. After some time it was decided to translate the whole thing to use the string-passing method, which is now the default method. Here in the Institute of Computer Science of the Hebrew University of Jerusalem, they have finally thought of taking all papers and replacing them with computer data. This process was intended to include scanning of documents, and storing the resulting TIFF images for future reference. Also, Postgres relations have been defined for tracing office issues such as inventory. In one of the relations, each tuple represents an inventory item, and one of the attributes is an array of text elements. This attribute lists names of documents associated with the inventory item, which are TIFF images stored as regular Unix files. It was desired that the user of xpg could use this attribute easily for browsing the images, and this is how it is done (with some modifications for simplicity): - All images are stored under a single directory, /images . - We would like to use two commands with the TIFF images: xtiff and xpaint. Both programs can handle the TIFF images. - The attribute, as mentioned, is an array of text elements, each representing the name of a TIFF image. In our xpg resource file, we have included the lines: Xpg*arrayCmd1: xtiff %% Xpg*arrayCmdPath1: /images Xpg*arrayCmdName1: xtiff Xpg*arrayCmd2: xpaint %% Xpg*arrayCmdPath2: /images Xpg*arrayCmdName2: xpaint Now, in order to view the images for a specific inventory item, we first double-click the array attribute. The Array Dialog opens. Now, we select the item's tuple. As a result, the Array Dialog updates to list the elements of the item's array, ie. the image names. We have two command buttons visible, labeled xtiff and xpaint (The third button is not visible because no command was defined for it.) We also have a button for closing the Array Dialog. Now we can simply select one of the image names in the list, maybe "letter.tiff", and press one of the command buttons, say the "xpaint" button. xpg spawns a child process to continue the job: this child first chdir's to /images, then replaces the "%%" string in arrayCmd2 with the image name, and executes the result, which is "xpaint letter.tiff". We can repeat this procedure with other image names listed in the Array Dialog, or select new tuples; we should not forget to quit these external programs when we finish using them, because xpg will not do this for us.