4D v13.4

Interaction between components and host databases

Home

 
4D v13.4
Interaction between components and host databases

Interaction between components and host databases  


 

When a component has been installed in a host database, its name appears on the Current form table of the Explorer of the host database, in the Component Methods theme. Shared project methods are listed as hierarchical lists and, if the component is interpreted, their contents can be displayed in the preview area.

For more information about the definition of shared methods, refer to Sharing of project methods.

Certain types of objects defined by a component evolve in their own execution space, which eliminates the possibility of conflicts arising with the existing objects of the host database and those of other components. These objects are called “unshared” or “partitioned.” For example, variables are partitioned, which means that a <>Myvar variable of the Longint type that is created and used by a component can coexist with a <>Myvar variable of the Text type that is created and used by the host database (or by another component). 

Other objects share the same execution space between the host database and the components. Using these objects requires more precautions to be taken but permits the host database and the components to communicate with each other. These objects are called “shared” or “non-partitioned”. 

For example, sets are non-partitioned, which means that if a component creates the mySet set, it will be deleted if the host database executes the statement:

 CLEAR SET(mySet)

The following objects are unshared (partitioned) between the components and the host databases:

  • Style sheets
  • Help tips
  • Choice lists
  • Library pictures
  • Menus and menu bars created via the Menu editor
  • Project methods not having the “Shared by components and host database” property
  • Semaphores
  • Processes
  • Variables (local, process and interprocess)
  • System variables (OK, Document, etc.)
  • Table forms
  • Project forms that do not have the "Publishsed as subform" property
  • Resources and references to open resources files

The following objects are shared (non-partitioned) between components and host databases:

  • Sets
  • Named selections
  • Hierarchical lists using a reference (created using the New list, Load list, Copy list or BLOB to list commands)
  • Menus and menu bars using the ID returned by the Create menu command.
  • Project methods with the “Shared by components and host database” property
  • Project forms with the "Published as subform in the host database" property
  • XML structure references
  • Open file references (except for resources files)
  • Pointers

Note: Of course, unusable objects found in the matrix database are ignored by the host database (see Usable and unusable objects).

All the project methods of a matrix database are by definition included in the component (the database is the component), which means that they can be called and executed by the component. 

On the other hand, by default these project methods will not be visible, nor can they be called in the host database. In the matrix database, you must explicitly designate the methods that you want to share with the host database. These project methods will be visible on the Current form table of the Explorer and can be called in the code of the host database (but they cannot be modified in the Method editor of the host database). These methods form entry points in the component. 

Conversely, for security reasons, by default a component cannot execute project methods belonging to the host database. In certain cases, you may need to allow a component to access the project methods of your host database. To do this, you must explicitly designate the project methods of the host database that you want to make accessible to the components. 

This configuration is carried out via the Shared by components and host database property in the Method Properties dialog box:

You can also apply this property to several different methods at once using the Batch setting of attributes dialog box that is available using the context menu of the Explorer (see Batch setting for method attributes).

The effect of this option is defined by the context of the database use: if the database is used as a component, the method will be accessible in the host database and visible in the Explorer. If the database is a host database, the method will be usable by the components.

You can share the forms of the matrix database and use them as subforms in the host database.

On the component side (matrix database), only project subforms can be specified as published subforms. 

For a component form to be selected as a subform in a host database, it must have been explicitly designated as a "published form" in the properties dialog box of the form via the new Published as subform in the host database option:

Note: This dialog box can be accessed via the Form Properties... command of the context menu or from the action menu of the Explorer (see Form Properties (Explorer)). 

You must manage the interactions between the subform and the parent forms of the host database using the mechanisms and tools described in Page subforms.

On the host database side, it is imperative that subforms coming from components must be used in page mode: in the form editor, when the subform object is selected in the parent form, deselect the Output subform option in the "Sub-Form" theme of the Property list. 

Then, choose <None> in the "Table" menu. The forms published by the components are then listed in the "Detail Form" menu. Their name is followed by that of the component in parentheses. You can simply choose from this list the form to be used in the "Detail Form" list.

A new instance of the selected object is then immediately created in the form.

The local, process and interprocess variables are not shared between components and host databases. The only way to access component variables from the host database and vice versa is using pointers. 

Example using an array:

  • In the host database:
     ARRAY INTEGER(MyArray;10)
     AMethod(->MyArray)
  • In the component, the AMethod project method contains:
     APPEND TO ARRAY($1->;2)

Examples using variables:

 C_TEXT(myvariable)
 component_method1(->myvariable)
 C_POINTER($p)
 $p:=component_method2(...)

When you use pointers to allow components and the host database to communicate, you need to take the following specificities into account:

  • The Get pointer command will not return a pointer to a variable of the host database if it is called from a component and vice versa.
  • The component architecture allows the coexistence, within the same interpreted database, of both interpreted and compiled components (conversely, only compiled components can be used in a compiled database). In order to use pointers in this case, you must respect the following principle: the interpreter can unpoint a pointer built in compiled mode; however, in compiled mode, you cannot unpoint a pointer built in interpreted mode.
    Let’s illustrate this principle with the following example: given two components, C (compiled) and I (interpreted), installed in the same host database.
    • If component C defines the myCvar variable, component I can access the value of this variable by using the pointer ->myCvar.
    • If component I defines the myIvar variable, component C cannot access this variable by using the pointer ->myIvar. This syntax causes an execution error.
  • The comparison of pointers using the RESOLVE POINTER command is not recommended with components since the principle of partitioning variables allows the coexistence of variables having the same name but with radically different contents in a component and the host database (or another component). The type of the variable can even be different in both contexts.
    If the myptr1 and myptr2 pointers each point to a variable, the following comparison will produce an incorrect result:
     RESOLVE POINTER(myptr1;vVarName1;vtablenum1;vfieldnum1)
     RESOLVE POINTER(myptr2;vVarName2;vtablenum2;vfieldnum2)
     If(vVarName1=vVarName2)
      //This test returns True even though the variables are different

    In this case, it is necessary to use the comparison of pointers:
     If(myptr1=myptr2) //This test returns False

Although components cannot use tables, the following commands can be called within a component:

DEFAULT TABLE
NO DEFAULT TABLE
Current default table

In fact, these commands are useful when a component must use tables of the host database. The pointers will permit the host database and the component to communicate with each other in this case. For example, here is a method that could be called from a component:

 C_LONGINT($1//Number of a table in host database
 $tablepointer:=Table($1)
 DEFAULT TABLE($tablepointer->)
 CREATE RECORD //Use the default table of the host database
 $fieldpointer:=Field($1;1)
 $fieldpointer->:="value"
 SAVE RECORD

Except for Unusable commands, a component can use any command of the 4D language. 

When commands are called from a component, they are executed in the context of the component, except for the EXECUTE METHOD command that uses the context of the method specified by the command. Also note that the read commands of the “Users and Groups” theme can be used from a component but will read the users and groups of the host database (a component does not have its own users and groups). 

The SET DATABASE PARAMETER and Get database parameter commands are an exception: their scope is global to the database. When these commands are called from a component, they are applied to the host database. 

Furthermore, specific measures have been specified for the Structure file and Get 4D folder commands when they are used in the framework of components (see the Language Reference manual).

The COMPONENT LIST command can be used to obtain the list of components that are loaded by the host database.

When you use components that are not compiled, their code appears in the standard debugger of the host database. 

The debugger respects the execution space of partitioned objects. If you display the value of the var1 variable of the host database in the custom watch pane then execute the code belonging to the component also containing a var1 variable, the value displayed will not be updated. You must display another instance of the variable in the custom watch pane to obtain its value in the current context.

 
PROPERTIES 

Product: 4D
Theme: Developing and installing 4D components