Building a Mediator

Step 4: Defining the mediator - relationships

The last step is to define the relationships. (This is presuming you declared some relationships in your ODL, which you don't need to do.) This is done in the same way as the attributes, by inserting OQL into the relationship statements. However, the type of a relationship is the OID (or a collection of OIDs) for the target class. This means that the OQL statement must return the same type as the elements in the extent of the target class.

For example, suppose that the OQL inserted into the extent clause of the Project class produced a set of strings containing the name of each project. Then for our member_of_projects relationship we want to write OQL that returns the names of all of the projects of which the person is a member:

  select distinct t.project_name from Teams t where self in t.member_IDs;

For manager_of_projects we want the names of all of the projects of which the person is the manager:

  select distinct t.project_name from Teams t where t.manager_ID = self;

Putting it all together:

  classdef Person (extent People { select distinct p.ID from Phonebook p; })
  {
    attribute String name {
        element(select p.fullname from Phonebook p where p.ID = self);
    };
    attribute integer salary {
        element(
          select trunc(emp.pay_percentage * range.max_salary)
          from Payroll_PayEmps emp, Payroll_PayRanges range
          where emp.Emp_ID = self and emp.range_ID = range.ID
        );
    };

    relationship set member_of_projects {
        select distinct t.project_name from Teams t where self in t.member_IDs;
    } inverse Project::team;
    relationship set manager_of_projects {
        select distinct t.project_name from Teams t where t.manager_ID = self;
    } inverse Project::manager;
  }

As another example, here's how we might define the Project class we specified at the beginning:

  classdef Project (extent Projects { select distinct t.project_name from Teams t; })
  {
    attribute String name { self; };
    attribute integer budget {
        sum(select t.total_budget from Teams t where t.project_name = self);
    };

    relationship set team {
        select distinct m
        from Teams t, t.member_IDs m
        where t.project_name = self;
    } inverse Person::member_of_projects;
    relationship Person manager {
        element(
          select distinct t.manager_ID
          from Teams t
          where t.project_name = self
        );
    } inverse Person::manager_of_projects;
  }

Notice that we're using self itself as the value of the name attribute. That's because it was defined in the extent as the name of the project, which is exactly what we want. Also notice that the manager relationship uses the elementfunction, since it is a one-to-many relationship.

Once you have defined the extents, attributes, and relationships, you're done! You can now use your mediator.


[Tech Docs Index]