The DataBlade API provides the following functions for accessing collection data types.
When you open a collection cursor with mi_collection_open( ), the cursor position points to the first element of the collection. The cursor position identifies the current element in the collection cursor. The DataBlade API functions that access a collection must specify where in the collection to perform the operation. To specify location, these functions all have an action argument of type MI_CURSOR_ACTION, which supports the cursor-action constants in Table 21.
The following code fragment uses the mi_collection_fetch( ) function to fetch a VARCHAR element from a collection:
/* * Fetch next VARCHAR( ) element from a collection. */ MI_CONNECTION *conn; MI_COLL_DESC *colldesc; MI_ROW_DESC *rowdesc; MI_COLLECTION *nest_collp; MI_DATUM value; mi_integer ret_code, ret_len; char *buf; /* Fetch a VARCHAR( ) type */ ret_code = mi_collection_fetch(conn, colldesc, MI_CURSOR_NEXT, 0, &value, &ret_len); switch ( ret_code ) { case MI_NORMAL_VALUE: buf = mi_get_vardata((mi_lvarchar *)value); DPRINTF("trace_class", 15, ("Value: %s", buf)); break; case MI_NULL_VALUE: DPRINTF("trace_class", 15, ("NULL")); break; case MI_ROW_VALUE: rowdesc = (MI_ROW_DESC *)value; break; case MI_COLLECTION_VALUE: nested_collp = (MI_COLLECTION *)value; break; case MI_END_OF_DATA: DPRINTF("trace_class", 15, ("End of collection reached")); return (100); }
You insert an element into an open collection with the mi_collection_insert( ) function. You can perform an insert operation only on a read/write cursor. An insert is not valid on a read-only cursor.
The mi_collection_insert( ) function uses an MI_DATUM value to represent an element that it inserts into a collection. The contents of the MI_DATUM structure depend on the passing mechanism that the function used, as follows:
The mi_collection_insert( ) function inserts the new element at the location in the collection cursor that its action argument specifies. For a list of valid cursor-action flags, see Table 21.
The following call to mi_collection_insert( ) can pass in an actual value because it inserts an INTEGER element into a LIST collection and integer values are passed by value in a C UDR:
MI_CONNECTION *conn; MI_DATUM datum; MI_COLL_DESC *colldesc; datum=6; mi_collection_insert(conn, colldesc, datum, MI_CURSOR_ABSOLUTE, 1); datum=3; mi_collection_insert(conn, colldesc, datum, MI_CURSOR_ABSOLUTE, 2); datum=15; mi_collection_insert(conn, colldesc, datum, MI_CURSOR_ABSOLUTE, 3); datum=1; mi_collection_insert(conn, colldesc, datum, MI_CURSOR_ABSOLUTE, 4); datum=4; mi_collection_insert(conn, colldesc, datum, MI_CURSOR_ABSOLUTE, 5); datum=8; mi_collection_insert(conn, colldesc, datum, MI_CURSOR_ABSOLUTE, 6);
Figure 17 shows the cursor position after the preceding calls to mi_collection_insert( ) complete.
These mi_collection_insert( ) calls specify absolute addressing (MI_CURSOR_ABSOLUTE) for the collection because the collection is defined as a LIST. Only LIST collections have ordered position assigned to their elements. SET and MULTISET collections do not have ordered position of elements.
You fetch an element from an open collection with the mi_collection_fetch( ) function. You can perform a fetch operation on a read/write or a read-only cursor. To fetch a collection element, you must specify:
The mi_collection_fetch( ) function obtains the element specified by its action argument from the collection cursor. For a list of valid cursor-action flags, see Table 21. You can move the cursor position back to the beginning of the cursor with the mi_collection_fetch( ) function, as the following example shows:
mi_collection_fetch(conn, coll_desc, MI_CURSOR_FIRST, 0, coll_element, element_len); if ( ((mi_integer)coll_element != 1) || (element_len != sizeof(mi_integer)) ) /* raise an error */
This function moves the cursor position backward with respect to its position after a call to mi_collection_insert( ) (Figure 17). The mi_collection_fetch( ) function is valid only for the following kinds of cursors:
Only scroll cursors provide the ability to move the cursor position forward and backward.
Figure 18 shows the cursor position and coll_element value after the preceding call to mi_collection_fetch( ).
Figure 19 shows the cursor position and value of coll_element after the following mi_collection_fetch( ) call:
mi_collection_fetch(conn, coll_desc, MI_CURSOR_NEXT, 0, coll_element, element_len);
Figure 20 shows the cursor position and value of coll_element after the following mi_collection_fetch( ) call:
mi_collection_fetch(conn, coll_desc, MI_CURSOR_RELATIVE, 3,
coll_element, element_len);
The preceding mi_collection_fetch( ) call is valid only if the collection is a LIST. Only LIST collections are ordered. Therefore relative fetches, which specify the number of elements to move forward or backward, can only be used on LIST collections. If you try to perform a relative fetch on a SET or MULTISET, mi_collection_fetch( ) generates an error.
Figure 21 shows the cursor position and value of coll_element after the following mi_collection_fetch( ) call:
mi_collection_fetch(conn, coll_desc, MI_CURSOR_RELATIVE, -2, coll_element, element_len);
Because the preceding mi_collection_fetch( ) call moves the cursor position backward, the call is valid only if the collection cursor is a scroll cursor. When you open a collection with mi_collection_open( ), you get a read/write scroll collection cursor. However, if you open the collection with mi_collection_open_with_options( ) and the MI_COLL_NOSCROLL option, mi_collection_fetch( ) generates an error.
Figure 22 shows the cursor position and value of coll_element after the following mi_collection_fetch( ) call:
mi_collection_fetch(conn, coll_desc, MI_CURSOR_ABSOLUTE, 6, coll_element, element_len);
The preceding mi_collection_fetch( ) call is valid only if the collection is a LIST. Because absolute fetches specify a position within the collection by number, they can only be used on an ordered collection (a LIST). If you try to perform an absolute fetch on a SET or MULTISET, mi_collection_fetch( ) generates an error.
Because only six elements are in this collection, the absolute fetch of 6 positions the cursor on the last element in the collection. This result is the same as if you had issued the following mi_collection_fetch( ):
mi_collection_fetch(conn, coll_desc, MI_CURSOR_LAST, 0, coll_element, element_len);
The fetch last is useful when you do not know the number of elements in a collection and want to obtain the last one.
The mi_collection_fetch( ) function uses an MI_DATUM value to represent an element that it fetches from a collection. You must pass in a pointer to the value buffer in which mi_collection_fetch( ) puts the element value. However, you do not have to allocate memory for this buffer. The mi_collection_fetch( ) function handles memory allocation for the MI_DATUM value that it passes back.
The contents of the MI_DATUM structure that holds the retrieved element depends on the passing mechanism that the function used, as follows:
You declare a value buffer for the fetched element and pass in the address of this buffer to mi_collection_fetch( ). You can declare the buffer in either of the following ways:
Declare the value buffer as a pointer to the field data type, regardless of whether the data type is passed by reference or by value.
Your code can dynamically determine the field type with the mi_column_type_id( ) or mi_column_typedesc( ) function. You can then convert (or cast) the MI_DATUM value to a data type that you need.
Figures Figure 18 through Figure 22 fetch elements from a LIST collection of INTEGER values. To fetch elements from this LIST, you can declare the value buffer as follows:
mi_integer *coll_element;
Because you can pass INTEGER values by value in a C UDR, you access the MI_DATUM structure that these calls to mi_collection_fetch( ) pass back as the actual value, as follows:
int_element = (mi_integer)coll_element;
If the element type is a data type that must be passed by reference, the contents of the MI_DATUM structure that mi_collection_fetch( ) passes back is a pointer to the actual value. The following call to mi_collection_fetch( ) also passes in the value buffer as a pointer. However, it passes back an MI_DATUM value that contains a pointer to a FLOAT (mi_double_precision) value:
mi_double_precision *coll_element, flt_element; ... /* Fetch a FLOAT value in a C UDR */ mi_collection_fetch(conn, coll_desc, action, jump, &coll_element, &retlen); flt_element = *coll_element;
For the fetches in Figures Figure 18 through Figure 22, a client LIBMI application declares the value buffer in the same way as a C UDR. However, because all data types are passed back by reference, the MI_DATUM structure that mi_collection_fetch( ) passes back contains a pointer to the INTEGER value, not the actual value itself:
mi_integer *coll_element, int_element; ... /* Fetch an INTEGER value in a client LIBMI application */ mi_collection_fetch(conn, coll_desc, action, jump, &coll_element, &retlen); int_element = *coll_element;
You update an element in an open collection with the mi_collection_update( ) function. You can perform an update operation only on a read/write cursor. An update is not valid on a read-only cursor.
The mi_collection_update( ) function uses an MI_DATUM value to represent the new value for the element it updates in a collection. The contents of this MI_DATUM structure depend on the passing mechanism that the function used, as follows:
The mi_collection_update( ) function updates the element at the location in the collection cursor that its action argument specifies. For a list of valid cursor-action flags, see Table 21.
The following code shows an example of using the mi_collection_update( ) function to update the first element in a collection:
/* * Update position 1 in the collection to contain 3.0 * Note that single-precision value is passed by REFERENCE. */ MI_CONNECTION *conn; MI_COLL_DESC *colldesc; MI_DATUM val; mi_integer ret, jump; mi_real value; /* Update 1st element to 3.0 */ value = 3.0; val = (MI_DATUM)&value; jump = 1; DPRINTF("trc_class", 11, ("Update set value %d @%d", value, jump)); /* Pass single-precision values by reference */ ret = mi_collection_update(conn, colldesc, val, MI_CURSOR_ABSOLUTE, jump); if ( ret != MI_OK ) { DPRINTF("trc_class", 11, ("Update @%d value %d MI_CURSOR_ABSOLUTE\ failed", jump, value)); }
You delete an element from an open collection with the mi_collection_delete( ) function. You can perform a delete operation only on a read/write cursor. A delete is not valid on a read-only cursor.
The mi_collection_delete( ) function deletes the element at the location in the collection cursor that its action argument specifies. For a list of valid cursor-action flags, see Table 21.
The following code shows an example of using the mi_collection_delete( ) function to delete the last element of a collection:
/* * Delete last element in the collection */ MI_CONNECTION *conn; MI_COLL_DESC *coll_desc; mi_integer ret; ret = mi_collection_delete(conn, coll_desc, MI_CURSOR_LAST, 0);
The DataBlade API provides the mi_collection_card( ) function for obtaining the number of elements in a collection (its cardinality). The following code fragment uses the mi_collection_card( ) function to perform separate actions based on whether a collection is NULL or has elements (possibly 0 elements):
MI_COLLECTION *collp; mi_integer cardinality; mi_boolean isnull; /* Attach collp to a collection */ cardinality = mi_collection_card(collp, &isnull); if ( isnull == MI_TRUE ) { mi_db_error_raise(conn, MI_MESSAGE, "Warning: Collection is NULL."); } else { if ( cardinality > 0 ) { /* Open collection and perform action on individual elements */ } }Enterprise Edition Home | Express Edition Home | [ Top of Page | Previous Page | Next Page | Contents | Index ]