Uniform Database Access

The Uniform Database Access (UDA) API allows C and C++ applications to bypass the native, generated, API and use a pre-defined generic navigational API to access the database.

How it Works

The database dictionary generated by the mcocomp schema compiler for all native API calls is coded into the .c output file. In the output the dictionary is followed by the generated schema-specific type safe API functions. These comprise the application specific API (generated API) used by the application developer to access specific fields, indexes and array elements.

Note that these individual functions all call low level mco_wrapper functions like mco_w_new_obj_oid(), mco_w_obj_delete(), etc. These wrapper functions provide a “generic” interface to access individual database objects. However their implementation requires an intimate knowledge of the database dictionary in order to correctly specify the integer values for function parameters. This is the work of the mcocomp compiler.

The UDA API is designed to provide a similar “generic” interface for applications that does not require intimate knowledge of the database dictionary. To this end, the UDA registry (Dictionary and Meta-Dictionary) functions provide the means to enumerate fields, indexes and array elements so that the application developer can access them by name. The integer values returned by the registry functions are then passed to UDA access functions like mco_uda_new(), mco_uda_delete(), etc. Notice that the type-safety provided by the C compiler when using native API calls is sacrificed for the flexibility of these generic UDA access functions.

Typically, an application developer will build “helper” functions like the following to make calls to the UDA registry functions:

 
    unsigned short get_field_no(unsigned short struct_no, const char *field_name)
    {
        mco_dict_field_info_t field_info;
        if ( mco_dict_field_name(metadict, 0, struct_no, field_name, &field_info) 
                != MCO_S_OK) 
            return (unsigned short) -1;
             
        return field_info.field_no;
    }
 
    unsigned short get_struct_no(const char *struct_name)
    {
        mco_dict_struct_info_t struct_info;
        if (mco_dict_struct_name(metadict, 0, struct_name, &struct_info) 
                != MCO_S_OK) 
            return (unsigned short) -1;
             
        return struct_info.struct_no;
    }
 
    unsigned short get_index_no(const char *struct_name, const char *index_name)
    {
        mco_dict_index_info_t index_info;
        if (mco_dict_index_name(metadict, 0, get_struct_no(struct_name), 
                index_name, &index_info) != MCO_S_OK) 
            return (unsigned short) -1;
        return index_info.index_no;
    }
     

With these “helpers” in place, the following code snippet demonstrates calls to the UDA access functions to create and update a database object:

 
    mco_uda_object_handle_t rec;
    mco_uda_value_t value;
    uint4 key = 1999;
    unsigned short Record_struct_no, key_field_no,
            tkey_index_no, hkey_index_no;
 
    Record_struct_no = get_struct_no("Record");
    key_field_no     = get_field_no(Record_struct_no, "key");
    tkey_index_no    = get_index_no("Record", "tkey");
    hkey_index_no    = get_index_no("Record", "hkey");
     
    rc = mco_uda_new(t, Record_struct_no, 0, 0, 0, &rec);
    if (MCO_S_OK == rc)
    {
        value.type = MCO_DD_UINT4;
        value.v.u4 = key;
        rc = mco_uda_put(&rec, key_field_no, 0, &value);
    }
     

 

Please use the following links to view the APIs for specific UDA function categories:

Registry Registry functions
Fields and Indexes UDA Fields and Indexes
UDA Functions The UDA is a generic API
Database Control Database Open/Close Functions
Object Interfaces Object New/Delete/Checkpoint/Get/Put Functions
Vector Vector Functions
Cursor Cursor Functions
User-defined Indexes User-defined Indexes
Collation Collation implementation
Programming UDA Programming technique
Sequences UDA support for the sequence data type