Understanding Relates and Attaches

Data Dictionary objects perform relates and attaches to maintain your hierarchy of related records. Relates involves the finding of a related-to records in parent tables. Attaches involve the moving of related field data from a parent table to a child table. The relate and attach processes are mostly automatic. As long as your relationships are defined for your tables and your Data Dictionary classes, and your DDO structure is properly assembled, the Data Dictionaries will perform these operations at the proper time and in the proper manner.

The Attach Process

Attaches are performed before a save or a find. Within the DDO structure, each DDO that will participate in the save or find will be sent the message Attach_Main_File. This event attaches data by moving all related file buffer data from the parent table to the child table. The attach will only occurs if the parent DDO is part of the DDO structure.

There is often confusion about how attaches are used in a find resulting in finds appearing not to work. A find is based on the contents of the table’s file-buffer. Right before the actual find, Attach_Main_File is sent. As mentioned, this moves field data from the parent to the child. If your child file-buffer contained finding data in those fields they will be replaced with the field data from the parent. This means that the parent table file-buffers and not the child table file-buffers should be seeded with related data before a find.

For example, assume you wish to perform a find an Order table in Customer Number x Order Number sequence – presumably on an index that is OrderHea.Customer_Number x OrderHea.Order_Number.

Object oCustomer_DD is a Customer_DataDictionary

End_Object

 

Object oOrderHea_DD is an OrderHea_DataDictionary

    Set DDO_Server to oCustomer_DD

End_Object

:

 

// This will not work properly.

// Customer number is moved into the OrderHea File buffer

// and will be lost when the attach occurs before the find

Procedure FindNextOrder integer iCustomer integer iOrder

    Send Clear of oOrderHea_DD

    Move iCustomer to OrderHea.Customer_Number

    Move iOrder    to OrderHea.Order_Number

    Send Find of oOrderHea_DD GT 2

End_Procedure

:

 

// This will work properly.

// Customer number is moved into the Customer File buffer

// and will be attached before the find

Procedure FindNextOrder integer iCustomer integer iOrder

    Send Clear of oOrderHea_DD

    Move iCustomer to Customer.Customer_Number

    Move iOrder    to OrderHea.Order_Number

    Send Find of oOrderHea_DD GT 2

End_Procedure

The same applies to the Binding of a File.Field value in a DEO. You should always use the related-parent file.field and not the child

// This will not work properly.

Object oCustomerNumber is a dbForm

    Entry_Item OrderHea.Customer_Number

End_Object

 

// This will work properly.

Object oCustomerNumber is a dbForm

    Entry_Item Customer.Customer_Number

End_Object

Note that the parent to child attach only occurs if the parent DDO is part of the structure.

The Attach_Main_File event is discussed under Defining Data Dictionary Classes. Most of the time augmentations of this message will occur at the class level and will be used to model a custom relationship.

If you are augmenting Attach_Main_File at the object level you should be particularly careful about the save operation. The Attach_Main_File called right before a record is saved, is used to ensure that the child record contains the proper related field data. If you alter this, you could compromise database integrity.

It is possible to perform different attach actions for saves and find. You do this by checking the operation-mode of the DDO. This is done with the Operation_Mode global integer. In this sample, we will disable attaches for all finds but enable them for saves.

Object oOrderHea_DD is an OrderHea_DataDictionary

    // Disable attaches for finds but perform normal attaches with saves

    Procedure Attach_Main_File

        If (Operation_Mode=Mode_Saving) begin

            Forward send Attach_Main_File

        End

    End_Procedure

End_Object

 

The Relate Process

A relate occurs after any successful find. All related parent records are found and all parent DDOs are updated with the new record. This relate is internal – no message is sent to perform the actual relate.  The relate process ensures that a find updates you entire DDO structure. The main record and all of it’s parents, grand-parents, etc. will be found and loaded into your DDO structure.

Disabling Relates

The internal relate can be disabled by setting the No_Relate_State property to true. This would rarely be done at the class level, but might be used at the object level to improve finding speed. For example, you may need to search through a table but have no need to find all parent records.

Procedure FindRecord

    Handle hoDDO

    Boolean bTemp bFound

 

    Move oOrdeHea_DD to hoDDO

    Get No_Relate_State of hoDDO to bTemp

    Set No_Relate_State of hoDDO to True

    Send Find of hoDDO FIRST_RECORD 1

    Move (Found) to bFound

    While bFound

        Send ProcessRecord

        Send Find of hoDDO GT 1

        Move (Found) to bFound

    End

    Set No_Relate_State of hoDDO to bTemp

End_Procedure

 

Custom Relationships

After every find and relate the event Relate_Main_File is sent to every DDO that participated in the find. This is sent even if No_Relate_State is set True. This event allows you to model custom relationships. These kinds of custom relationships are almost always modeled in your class and not coded at the object level. See Relate_Main_File in Defining Data Dictionary Events for more on using this event.

See Also

Find and Clear Operations in DDOs