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.
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
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.
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
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.
Find and Clear Operations in DDOs