Step 1: Getting the Description of an ADT
This step demonstrates how to get the description of an ADT. An instance is retrieved. This gives us the description of the ADT, since an ADT is described using DB Link class IldADTDescriptor.
In this step, the following items are presented:
Objects and Abstract Data Types
There are various kinds of object types in an RDBMS. However, these object types can be different with Informix and Oracle®. DB Link provides two basic object types: IldObjectType and IldCollectionType. When an ADT column is retrieved, it will be one of these 2 types. IldObjectType may be the object type in Oracle, and named row or unnamed row in Informix. IldCollectionType may be varray or nested table types in Oracle, or nested table, list, set, or multiset in Informix Universal Server.
The IldADTDescriptor class provides an additional type name to give more information on the exact data type in the RDBMS. This is the IldADTType returned by getType. Depending on this type, you may want to access a specific ADT attribute. For instance, a varray is a specific kind of collection, since there is a limit to the maximum number of elements that can be recorded in the collection. This maximum number of elements can be retrieved from an IldADTDescriptor instance and is meaningful only for a varray ADT.
The following table summarizes the various ADT types handled by DB Link.
DB Link Column type 'IldColumnType' |
IldADTDescriptor type 'IldADTType' |
Database type |
IldObjectType |
IldADTObject |
Oracle® objects, and Informix [named] rows |
IldCollectionType |
IldADTTable |
Informix or Oracle nested tables |
IldCollectionType |
IldADTList |
Informix lists, sets, and multisets |
IldCollectionType |
IldADTArray |
Oracle varrays |
In DB Link, the various list types (IldADTTable, IldADTList, and IldADTArray) are manipulated in the same way. However, specific information that depends on the IldADTType can be retrieved.
To access an object type, you first create one within the database. This is done by the createADT(IldDbms*) method in source file ADTCommon.cpp.
Note
The SQL commands used to build the object data type depend on the database used—Oracle® or Informix US. |
The object structure is made from one or more of the following object data types:
-
POINT: A POINT object contains the coordinates of the point—two integer values X and Y.
-
LINE: A LINE object contains two POINT objects.
-
BRIDGE: A BRIDGE object contains a name and a nested object LINE.
-
BRIDGELST: A BRIDGELST object data type contains a list of bridges. With Informix, a data type name cannot be given to a collection. Therefore, the BRIDGELST data type cannot be created in this step. It will be created in Step 2, within a table.
All this makes for a complex nested object structure. This structure is described with DB Link.
Creating an ADT Instance
The program code first creates an IldADTDescriptor instance for the data type to be described. To do so, the name of the object data type is specified.
IldADTDescriptor* adt = 0 ;
if (!(adt = dbms->readAbstractType(checkCase(ADTName, dbms)))) {
IldDisplayError("Could not getADT description : ", dbms) ;
Ending(dbms) ;
exit(-1) ;
}
Note
In this call, the checkCase method is used. This ensures that the name of the data type is spelled in the correct case, depending on the RDBMS. With Informix, it is of the BRIDGE data type. With Oracle®, it is of the BRIDGELST data type. In this code excerpt, 'ADTName' contains this name—either BRIDGE for Informix or BRIDGELST for Oracle. |
Another way to get an IldADTDescriptor instance is to use the data type ID instead of its NAME. This is mainly useful for Informix data types that are not named: unnamed rows and the various kinds of collections. This method is not used here.
Displaying the Object Structure
Now the structure of the object is displayed. This is done recursively, since the object contains nested objects.
First, the type of the object is tested using method getType.
-
If the IldADTDescriptor object describes an object (IldObjectType), the following methods are used:
-
getAttributes - Returns an array of IldDescriptor objects. Each attribute of the ADT is described by one of these IldDescriptor objects.
-
getAttributesCount - Gives the number of attributes of the ADT. This is also the number of elements in the array returned by getAttributes.
-
-
When the object is a collection, it is built upon only one attribute. Hence, you do not have access to all the information (for example, the maximum number of elements in the list). To retrieve this additional information, the following methods are used:
-
getCollectionAttribute - This is equivalent to getAttributes, but it returns only one element.
-
getCollMaxSize - Returns the maximum number of elements in the list when the collection type is IldADTArray.
-
The code to get the description of the ADT is as follows (method displayADT):
IldUShort i = 0 ;
switch (adt->getType()) {
case IldADTObject : {
const IldDescriptor* const* elts = 0 ;
cout << "Object (" ;
elts = adt->getAttributes() ;
for (i = 0 ; i < adt->getAttributesCount() ; i++) {
displayDesc(dbms, elts[i]) ;
if (i < adt->getAttributesCount() - 1)
cout << ", " ;
}
cout << ")" ;
break ;
}
case IldADTList :
case IldADTArray : {
const IldDescriptor* desc = adt->getCollectionAttribute() ;
if (adt->getType() == IldADTList)
cout << "List of {" ;
else
cout << "List[" << adt->getCollMaxSize() << "] of {" ;
displayDesc(dbms, desc) ;
cout << "}" ;
break ;
}
default:
cout << "Unexpected ADT Type." << endl ;
}
Here, the IldDescriptor instances that describe each attribute of the ADT are retrieved from the IldADTDescriptor instance that describes the type. Then, the description of each of these attribute descriptions is printed.
Printing the ADT Attributes
Printing the ADT attributes is done by the method displayDesc. If one of the attributes is an object (nested object), the displayDesc method recursively calls displayADT to print the ADT description.
Here is an excerpt from method displayDesc:
cout << desc->getName() ;
switch (desc->getType()) {
case IldObjectType :
case IldCollectionType :
if (desc->getADTDescriptor()->isNamedType())
cout << "'" << desc->getSqlTypeName() << "' : " ;
displayADT(dbms, desc->getADTDescriptor()) ;
break ;
case IldStringType :
cout << desc->getSqlTypeName() << " (" << desc->getSize() << ")" ;
break ;
case IldIntegerType :
cout << desc->getSqlTypeName() ;
break ;
default:
cout << "Other type : " << desc->getType() << endl ;
}
Conclusion
This step demonstrated how to get the description of an Abstract Data Type. The two methods displayADT and displayDesc show how to go through the instance to get the description of the various attributes of the data type.
See ADTCommom.cpp source code (creation of the object types).
See main source code.