[ Previous | Next | Contents | Glossary | Home | Search ]
AIX Version 4.3 General Programming Concepts: Writing and Debugging Programs

Chapter 17. Object Data Manager (ODM)

Object Data Manager (ODM) is a data manager intended for storing system information. Information is stored and maintained as objects with associated characteristics. You can also use ODM to manage data for application programs.

System data managed by ODM includes:

You can create, add, change, get, show, delete, and drop objects and object classes with ODM. ODM commands provide a command line interface to these functions. ODM subroutines access these functions from within an application program.

Some object classes come with the system. These object classes are discussed in the documentation for the specific system products that provide them.

This documentation discusses:

ODM Object Classes and Objects

The basic components of ODM are object classes and objects. To manage object classes and objects, you use the ODM commands and subroutines. Specifically, you use the create and add features of these interfaces to build object classes and objects for storage and management of your own data.

An object class is a group of objects with the same definition. An object, a member of a defined object class, is an entity that requires storage and management of data. An object class is conceptually similar to an array of structures, with each object being a structure that is an element of the array.

An object class comprises one or more descriptors. Values are associated with the descriptors of an object when the object is added to an object class. The descriptors of an object and their associated values can be located and changed with ODM facilities.

For example, To create an object class called Fictional_Characters , enter:

class Fictional_Characters {
        char    Story_Star[20];
        char    Birthday[20];
        short   Age;
        char    Friend[20];
};

In this example, the Fictional_Characters object class contains four descriptors: Story_Star , Birthday , and Friend , which have a descriptor type of character and a 20-character maximum length; and Age , with a descriptor type of short. To create the object class files required by ODM, you process this file with the odmcreate command or the odm_create_class subroutine.

Once you create an object class, you can add objects to the class using the odmadd command or the odm_add_obj subroutine. For example, enter the following code with the odmadd command to add the objects Cinderella and Snow White to the Fictional_Characters object class, along with values for the descriptors they inherit:

Fictional_Characters:
        Story_Star      = "Cinderella"
        Birthday        = "Once upon a time"
        Age             = 19
        Friend          = "mice"
 
Fictional_Characters:
        Story_Star = "Snow White"
        Birthday = "Once upon a time"
        Age = 18
        Friend = "Fairy Godmother"

The Fictional_Characters diagram shows a conceptual picture of the Fictional_Characters object class with the two added objects Cinderella and Snow White .

After the Fictional_Characters object class is created and the objects Cinderella and Snow White are added, the retrieved data for 'Story_Star = "Cinderella"' is:

Cinderella:
        Birthday        = Once upon a time
        Age             = 19
        Friend          = mice

ODM Object Class and Object Storage

Attention: Making changes to files that define system object classes and objects can result in system problems. Consult with your system administrator before using the /usr/lib/objrepos directory as a storage directory for object classes and objects.

Each object class you create with an odmcreate command or odm_create_class subroutine is stored in a file as a C language definition of an array of structures. Each object you add to the object class with an odmadd command or an odm_add_obj subroutine is stored as a C language structure in the same file.

You determine the directory in which to store this file when you create the object class. See "Storing Object Classes and Objects" for storage criteria.

ODM Object Class Locking

ODM does not implicitly lock object classes or objects. The coordination of locking and unlocking is the responsibility of the applications accessing the object classes. However, ODM provides the odm_lock and odm_unlock subroutines to control locking and unlocking object classes by application programs.

The odm_lock subroutine processes a string that is a path name and can resolve in an object class file or a directory of object classes. The odm_lock subroutine returns a lock identifier and sets a flag to indicate that the specified object class or classes defined by the path name are in use.

When the odm_lock subroutine sets the lock flag, it does not disable use of the object class by other processes. If usage collision is a potential problem, an application program should explicitly wait until it is granted a lock on a class before using the class.

Another application cannot acquire a lock on the same path name while a lock is in effect. However, a lock on a directory name does not prevent another application from acquiring a lock on a subdirectory or the files within that directory.

To unlock a locked object class, use an odm_unlock subroutine called with the lock identifier returned by the odm_lock subroutine.

Creating an Object Class

Prerequisite Tasks or Conditions

Attention: Making changes to files that define system object classes and objects can result in system problems. Consult your system administrator before using the /usr/lib/objrepos directory as a storage directory for object classes and objects.
  1. Create the definition for one or more object classes in an ASCII file. "ODM Example Code and Output" shows an ASCII file containing several object class definitions.
  2. Specify the directory in which the generated object must be stored.

"ODM Object Class and Object Storage" discusses the criteria used at object-class creation time for determining the directory in which to store generated object classes and objects. Most system object classes and objects are stored in the /usr/lib/objrepos directory.

Procedure

Generate an empty object class by running the odmcreate command with the ASCII file of object class definitions specified as the ClassDescriptionFile input file.

Adding Objects to an Object Class

Prerequisite Tasks or Conditions

Attention: Making changes to files that define system object classes and objects can result in system problems. Consult your system administrator before using the /usr/lib/objrepos directory as a storage directory for object classes and objects.
  1. Create the object class to which the objects will be added. See "Creating an Object Class" for instructions on creating an object class.
  2. Create the definitions for one or more objects. "ODM Example Code and Output" shows an ASCII file containing several object definitions.
  3. Specify the directory in which the generated objects will be stored.

"ODM Object Class and Object Storage" discusses the criteria used at object class creation time for determining the directory in which to store generated object classes and objects. Most system object classes and objects are stored in the /usr/lib/objrepos directory.

Procedure

Add objects to an empty object class by running the odmadd command with the ASCII file of object definitions specified as the InputFile input file.

Storing Object Classes and Objects

Prerequisite Tasks or Condition

Create an object or object class.

Procedure

Storage methods vary according to whether commands or subroutines are used to create object classes and objects.

Attention: Making changes to files that define system object classes and objects can result in system problems. Consult your system administrator before using the /usr/lib/objrepos directory as a storage directory for object classes and objects.
Using ODM Commands

When using the odmcreate or odmdrop command to create or drop an object class, specify the directory from which the class definition file will be accessed as follows:

  1. Store the file in the default directory indicated by $ODMDIR, which is the /usr/lib/objrepos directory.
  2. Use the set command to set the ODMDIR environment variable to specify a directory for storage.
  3. Use the unset command to unset the ODMDIR environment variable and the cd command to change the current directory to the one in which you want the object classes or objects stored. Then, run the ODM commands in that directory. The file defining the object classes and objects will be stored in the current directory.

When using the odmdelete, odmadd, odmchange, odmshow, or odmget command to work with classes and objects, specify the directory from which the class definition file will be accessed as follows:

  1. Store the file in the default directory indicated by $ODMDIR, which is the /usr/lib/objrepos directory.
  2. Use the set command to set the ODMDIR environment variable to specify a directory for storage.
  3. Use the unset command to unset the ODMDIR environment variable and the cd command to change the current directory to the one in which you want the object classes or objects stored. Then, run the ODM commands in that directory. The file defining the object classes and objects will be stored in the current directory.
  4. From the command line, use the set command to set the ODMPATH environment variable to a string containing a colon-separated list of directories to be searched for classes and objects. For example:
    $ export ODMPATH = /usr/lib/objrepos:/tmp/myrepos
    The directories in the $ODMPATH are searched only if the directory $ODMDIR does not have the class definition file.
Using the odm_create_class or odm_add_obj Subroutines

When the odm_create_class or odm_add_obj subroutine is used to create object classes and objects:

ODM Descriptors

An Object Data Manager (ODM) descriptor is conceptually similar to a variable with a name and type. When an object class is created, its descriptors are defined like variable names with associated ODM descriptor types. When an object is added to an object class, it gets a copy of all of the descriptors of the object class. Values are also associated with object descriptors already stated.

ODM supports several descriptor types:

Terminal descriptor Defines a character or numerical data type.
Link descriptor Defines a relationship between object classes.
Method descriptor Defines an operation or method for an object.

Use the descriptors of an object and their associated values to define criteria for retrieving individual objects from an object class. Format the selection criteria you pass to ODM as defined in "ODM Object Searches". Do not use the binary terminal descriptor in search criteria because of its arbitrary length.

ODM Terminal Descriptors

Terminal descriptors define the most primitive data types used by ODM. A terminal descriptor is basically a variable defined with an ODM terminal descriptor type. The terminal descriptor types provided by ODM are:

short Specifies a signed 2-byte number.
long Specifies a signed 4-byte number.
ulong Specifies an unsigned 4-byte number.
binary Specifies a fixed-length bit string. The binary terminal descriptor type is defined by the user at ODM creation time. The binary terminal descriptor type cannot be used in selection criteria.
char Specifies a fixed-length, null-terminated string.
vchar Specifies variable-length, null-terminated string. The vchar terminal descriptor type can be used in selection criteria.

ODM Link Descriptor

The ODM link descriptor establishes a relationship between an object in an object class and an object in another object class. A link descriptor is a variable defined with the ODM link descriptor type.

For example, the following code can be processed by the ODM create facilities to generate the Friend_Table and Fictional_Characters object classes:

class Friend_Table {
        char    Friend_of[20];
        char    Friend[20];
}; 
 
  class Fictional_Characters {
        char    Story_Star[20];
        char    Birthday[20];
        short   Age;
        link    Friend_Table Friend_Table Friend_of Friends_of;
};

The Fictional_Characters object class uses a link descriptor to make the Friends_of descriptors link to the Friend_Table object class. To resolve the link, the Friends_of descriptor retrieves objects in the Friend_Table object class with matching data in its Friend_of descriptors. The link descriptor in the Fictional_Characters object class defines the class being linked to (Friend_Table ), the descriptor being linked to (Friend_of ), and the name of the link descriptor (Friends_of ) in the Fictional_Characters object class.

The following code could be used to add objects to the Fictional_Characters and Friend_Table object classes:

Fictional_Characters:
        Story_Star      = "Cinderella"
        Birthday        = "Once upon a time"
        Age             = 19
        Friends_of      = "Cinderella"
Fictional_Characters:
        Story_Star      = "Snow White"
        Birthday        = "Once upon a time"
        Age             = 18
        Friends_of      = "Snow White"
Friend_Table:
        Friend_of       = "Cinderella"
        Friend          = "Fairy Godmother"
Friend_Table:
        Friend_of       = "Cinderella"
        Friend          = "mice"
Friend_Table:
        Friend_of       = "Snow White"
        Friend          = "Sneezy"
Friend_Table:
        Friend_of       = "Snow White"
        Friend          = "Sleepy"
Friend_Table:
        Friend_of       = "Cinderella"
        Friend          = "Prince"
Friend_Table:
        Friend_of       = "Snow White"
        Friend          = "Happy"

The figure shows a conceptual picture of the Fictional_Characters and Friend_Table object classes, the objects added to the classes, and the link relationship between them:

After the Fictional_Characters and Friend_Table object classes are created and the objects are added, the retrieved data for Story_Star = 'Cinderella' would be:

Cinderella:
        Birthday         = Once upon a time
        Age              = 19
        Friends_of       = Cinderella
        Friend_of        = Cinderella

To see the expanded relationship between the linked object classes, use the odmget command on the Friend_Table object class. The retrieved data for the Friend_of = 'Cinderella' object class would be:

Friend_Table:
        Friend_Of = "Cinderella"
        Friend = "Fairy Godmother"
 
Friend_Table:
        Friend_of = "Cinderella"
        Friend= "mice"
 
Friend_Table:
        Friend_of = "Cinderella"
        Friend = "Prince"

ODM Method Descriptor

The ODM method descriptor gives the definition of an object class with objects that can have associated methods or operations. A method descriptor is a variable defined with the ODM method descriptor type.

The operation or method descriptor value for an object is a character string that can be any command, program, or shell script run by method invocation. A different method or operation can be defined for each object in an object class. The operations themselves are not part of ODM; they are defined and coded by the application programmer.

The method for an object is called by a call to the odm_run_method subroutine. The invocation of a method is a synchronous event, causing ODM operation to pause until the operation is completed.

For example, the following code can be input to the ODM create facilities to generate the Supporting_Cast_Ratings object class:

class Supporting_Cast_Ratings {
        char    Others[20];
        short   Dexterity;
        short   Speed;
        short   Strength;
        method  Do_This;
};

In the example, the Do_This descriptor is a method descriptor defined for the Supporting_Cast_Ratings object class. The value of the method descriptor can be a string specifying a command, program, or shell script for future invocation by an odm_run_method subroutine.

The following code is an example of how to add objects to the Supporting_Cast_Ratings object class:

Supporting_Cast_Ratings:
        Others          = "Sleepy"
        Dexterity       = 1
        Speed           = 1
        Strength        = 3
        Do_This   = "echo Sleepy has speed of 1"
Supporting_Cast_Ratings:
        Others          = "Fairy Godmother"
        Dexterity       = 10
        Speed           = 10
        Strength        = 10
        Do_This   = "odmget -q "Others='Fairy Godmother'" Supporting_Cast_Ratings"

The Supporting_Cast_Ratings figure shows a conceptual picture of the Supporting_Cast_Ratings object class with the Do_This method descriptor and operations associated with individual objects in the class:

After the Supporting_Cast_Ratings object class is created and the objects are added, an invocation (by the odm_run_method subroutine) of the method defined for Sleepy would cause the echo command to display:

Sleepy has speed of 1

ODM Object Searches

Many ODM routines require that one or more objects in a specified object class be selected for processing. You can include search criteria in the form of qualifiers when you select objects with certain routines.

A qualifier is a null-terminated string parameter on ODM subroutine calls that gives the qualification criteria for the objects to retrieve. The descriptor names and qualification criteria specified by this parameter determine which objects in the object class are selected for later processing. Each qualifier contains one or more predicates connected with logical operators. Each predicate consists of a descriptor name, a comparison operator, and a constant.

A qualifier with three predicates joined by two logical operators follows:

SUPPNO=30 AND (PARTNO>0 AND PARTNO<101)

In this example, the entire string is considered the qualifier. The three predicates are SUPPNO=30 , PARTNO>0 , and PARTNO<101 , and the AND logical operator is used to join the predicates. In the first predicate, SUPPNO is the name of the descriptor in an object, the = (equal sign) is a comparison operator, and 30 is the constant against which the value of the descriptor is compared.

Each predicate specifies a test applied to a descriptor that is defined for each object in the object class. The test is a comparison between the value of the descriptor of an object and the specified constant. The first predicate in the example shows an = (equal to) comparison between the value of a descriptor (SUPPNO) and a constant (30) .

The part of the qualifier within parentheses:

PARTNO>0 AND PARTNO<101

contains two predicates joined by the AND logical operator. The PARTNO descriptor is tested for a value greater than 0 in the first predicate, then tested for a value less than 101 in the second predicate. Then the two predicates are logically concatenated to determine a value for that part of the qualifier. If PARTNO is the descriptor name for a part number in a company inventory, for example, this part of the qualifier defines a selection for all products with part numbers greater than 0 and less than 101.

In another example, the qualifier:

lname='Smith' AND Company.Dept='099' AND Salary<2500

can be used to select everyone (in ODM, every object) with a last name of Smith who is in Department 099 and has a salary less than $2500. Note that the Dept descriptor name is qualified with its Company object class to create a unique descriptor.

Descriptor Names in ODM Predicates

In ODM, a descriptor name is not necessarily unique. You can use a descriptor name in more than one object class. When this is the case, you specify the object class name along with the descriptor name in a predicate to create a unique reference to the descriptor.

Comparison Operators in ODM Predicates

The following are valid comparison operators:

= Equal to.
!= Not equal to.
> Greater than.
>= Greater than or equal to.
< Less than.
<= Less than or equal to.
LIKE Similar to; finds patterns in character string data.

Comparisons can be made only between compatible data types.

LIKE Comparison Operator

The LIKE operator enables searching for a pattern within a char descriptor type. For example, the predicate:

NAME LIKE 'ANNE'

defines a search for the value ANNE in the NAME descriptor in each object in the specified object class. In this case, the example is equivalent to:

NAME = 'ANNE'

You can also use the LIKE operator with the following pattern-matching characters and conventions:

Constants in ODM Predicates

The specified constant can be either a numeric constant or a character string constant.

Numeric Constants in ODM Predicates

Numeric constants in ODM predicates consist of an optional sign followed by a number (with or without a decimal point), optionally followed by an exponent marked by the letter E or e. If used, the letter E or e must be followed by an exponent that can be signed.

Some valid numeric constants are:

2            2.545   0.5   -2e5   2.11E0
+4.555e-10   4E0     -10    999   +42

The E0 exponent can be used to specify no exponent.

Character String Constants in ODM Predicates

Character string constants must be enclosed in single quotation marks:

'smith'   '91'

All character string constants are considered to have a variable length. To represent a single quotation mark inside a string constant, use two single quotation marks. For example:

'DON''T GO'

is interpreted as:

DON'T GO

AND Logical Operator for Predicates

The AND logical operator can be used with predicates. Use AND or and for the AND logical operator.

The AND logical operator connects two or more predicates. The qualifier example:

predicate1 AND predicate2 AND predicate3

specifies predicate1 logically concatenated with predicate2 followed by the result logically concatenated with predicate3 .

Related Information

List of ODM Commands and Subroutines.

ODM Example Code and Output.

ODM Error Codes in AIX Version 4.3 Technical Reference.

The odm_run_method subroutine.

The odmadd command, odmchange command, odmcreate command, odmdelete command, odmdrop command, odmget command, odmshow command.

The odm_create_class subroutine, odm_add_obj subroutine.


[ Previous | Next | Contents | Glossary | Home | Search ]