company logo

Using an access schema for accessing data in the data base

Using access schemata is a good technique for accessing data in hierarchical structures. An access schema is predefined hierarchy of properties which presents a specific view to the database. An access schema differs much from a traditional view definition, even though it fulfills similar tasks. In contrast to a view definition, an access schema is more flexible and much

easier to understand.

Access schemata are used in application programs as well as in OSI expressions. An access schema is simply defined by a hierarchy of properties. Considering the following example: In order to find out all persons that are not allowed to drive a car from the company, they are working on, the following access schema can be defined:

    Person

        company

            cars

                users

This is not the only way of defining an access schema for the problem. Usually, one may choose between many different access schemata and many different solutions. Nevertheless, this access schema visualizes, how an access schema works. The example below shows different ways of defining the access schema in an application program and in an OSI expression.

The hierarchy defined in an access schema has an important impact on the state of property handles. Thus, subordinated property handles are accessible only, when the an instance is selected in the parent property (handle). On the other hand the access schema provides automatic selection for relevant subordinated instances, i.e. selecting a person automatically provides the company collection the selected person is working for.

Of course, Access schemata are not always the best solution. In this case, the problem could simply be solved by a path expression:

    Person.Where( used_cars.GetCount() == 0 ).Print;

In many cases, however, an access schema is more transparent than an operation path or a traditional view definition.

// access schema in an OSI expression

{

VARIABLES

  SET<Person>   &rperson  = Person::Persons;

  SET<Company>  &rcompany = rperson.company;

  SET<Car>      &rcars    =        rcompany.cars;

  SET<Person>   &rusers   =                rcars.users;

  CHAR          &rpid     = rperson.pid;        

PROCESS  

  while ( rperson.next )

    while ( rcompany.next )

      while ( rcars.next )

        if ( !rusers.get(rpid).Exist ) // when not being a car user

          rperson.Print();

}

// access schema in a C++ program

  Property  rperson(database,"Person::Persons",Read);

  Property  rcompany(&rperson,"company"); // use pointer to parent

  Property  rcars(&rcompany,"cars");      // in order to get original property

  Property  rusers(&rcars,"users");

  Property  rpid(&rperson,"pid");

  while ( rperson.next() )

    while ( rcompany.next() )

      while ( rcars.next() )

        if ( !rusers.get(pid).Exist() )

          rperson.executeExpression("Print");