Finding references to objects

The EXPRESS function USEDIN returns each object that uses the specified object in a specified role, where the role is <schema_name>.<entity_name>.<attribute_name>. The C++ EXPRESS API has a similar construction. When object A is referencing another object (object B) by assigning object B to the appropriate attribute of object A, a pointer from B back to A is set. In this way it is easy to find all objects that are referencing object B. In other words; each object has a linked list of all other objects referencing itself. The API has a special iterator to traverse this linked list, the ReferencesIterator that is.
In the example below one iterates over all product_definition_formation objects referring to a specific product.
// Create a second product_definition_formation object
product_definition_formation* pdf2 = newObject(product_definition_formation);
pdf2->put_description("Aircraft with two front doors and wheel landing gear");
pdf2->put_id("2");
// Link product_definition_formation object to product object
pdf2->put_of_product(p1);
printf("\nVersion 2 for Product Aircraft 1 created.\n");
// Find product_definition_formation objects that are refering to product p1
printf("\nFind product_definition_formation objects that are refering to product p1");
ReferencesIterator<product_definition_formation*, entityType> pdfIter(p1,et_product_definition_formation);
product_definition_formation *mypdf;
for(mypdf = pdfIter.first(); mypdf; mypdf = pdfIter.next()){
printf("\nVersion %s for product %s\n",mypdf->get_id(),mypdf->get_of_product()->get_id());
}
If the program only needs one reference and/or there only exists one object of the specified type in the linked list, the getFirstReferencing(<wanted type> ) can be used.
Example:
// Find first referencing of type product_definition_formation
mypdf = (product_definition_formation*)p1->getFirstReferencing(et_product_definition_formation);
printf("\nFirst referencing version for product %s is version %s\n",mypdf->get_of_product()>get_id(),mypdf>get_id());
If you want to handle all referencing objects regardless of role, the AllReferencesIterator is available. The AllReferencesIterator has two constructors. The first one with no parameters will return all objects when traversing. The second constructor accepts an array of object types, where the last value is et_indeterminate, This array specifies which object types are to be returned from first/next methods, a filter in other words.
Example:
// Create a product catgory and connect the products to it
product_related_product_category *prpc = newObject(product_related_product_category);
prpc->put_name("Product category 1");
prpc->put_products_element(p1);
prpc->put_products_element(p2);
// Find all referencing
printf("\nFind all referencing product p1");
entityType myType;
AllReferencesIterator <entityType> productRefs(p1);
for (void *obj = productRefs.first(&myType); obj; obj = productRefs.next(&myType)) {
if(myType == et_product_definition_formation){
product_definition_formation pdf = (product_definition_formation)obj;
printf("\nReferencing : version %s for product %s",pdf->get_id(),pdf->get_of_product()->get_id());
}
if(myType == et_product_related_product_category){
product_related_product_category cat = (product_related_product_category)obj;
printf("\nCategory : %s",cat->get_name());
}
}