PreviousNext

Storing and Retrieving Persistent Objects

DCE provides a convenient database storage facility called the backing store, that lets you store and retrieve objects in a system-independent manner. The following implementation of a lookup function shows how to use a backing store database to lookup an object.

// FILE NAME: lookup.cxx
// This file contains the server lookup callout function
// specified by the [cxx_lookup] attribute in an ACF. It is called
// whenever an object cannot be found within the DCE runtime.

extern "C" {
#include <dce/dce.h> // standard DCE header file #include <dce/dbif.h> // backing store facility header file
}
#include "matrix_mgr.h"
#include <check_status.h>
#include "backing.h" // IDL generated header file
//
// This function performs the server management of object lookups.
// If the uuid_t parameter identifies one of the persistent objects,
// this function creates and returns the object.
//

Matrix *
object_lookup(uuid_t *key)
{
dce_db_handle_t db_h;
backing_data_s_t data;
int found;
unsigned32 status;
Matrix *matrix;

//
// Lookup the UUID's in a backing store database and get the data.
//
dce_db_open(
"backing.store",
0,
db_c_index_by_uuid | db_c_readonly,
(dce_db_convert_func_t) backing_data_convert,
&db_h,
&status
);

dce_db_fetch_by_uuid(
db_h,
key,
(void *) &data,
&status
); if (status != rpc_s_ok)
found = 0;
else
found = 1;

dce_db_close(&db_h, &status);

if (!found)
return 0;

// Found the object's data so create an instance of it.
matrix = new MatrixMgr(data.v00, data.v01, data.v10, data.v11);

// register the object so clients can find it directly
// and the server won't have to look it up again.
matrix->register_named_object((unsigned_char_t *) data.name);

return matrix;
}

The example is described as follows:

dce_db_open( )
Applications that have persistent objects commonly store in a database the information necessary to regenerate the object. In this example, the data is stored in a backing store data file (backing.store). The argument db_c_index_by_uuid | db_c_readonly indicates the file is opened for read-only access and to be indexed by UUID. The argument backing_data_convert is the function (defined in the backing interface) that the backing store facility uses to store or retrieve the data. A record for this database is also defined in the backing interface to contain the entry name and values for a two-by-two matrix. The backing interface is in the file backing.idl, and looks as follows:

[
uuid(3e9400dc-0895-11cf-abec-08002b39f4b8)
] interface backing
{
import "dce/database.idl";

/* Data: object name (for CDS) and values for 2-by-2 matrix */
typedef struct backing_data_s_t {
[string] char name[100];
int v00;
int v01;
int v10;
int v11;
} backing_data_s_t;

/* conversion function declaration */
void backing_data_convert(
[in] handle_t h,
[in,out] backing_data_s_t *data,
[in,out] error_status_t *st
);
}

dce_db_fetch_by_uuid( )
This DCE routine obtains the data for the object represented by the key UUID.

matrix = new MatrixMgr(data.v00, data.v01, data.v10, data.v11);
An instance of the persistent object is created for this server. Note that each server of the object would have its own implementation and instance of the object.

register_named_object((unsigned_char_t *) data.name);"
This function registers the object's name, UUID, and its server binding information with the cell's name service. It also registers the object's UUID and binding information with the host's endpoint map. Finally, this routine updates the runtime object table. As an option for more specific control, you can choose not to call this function and implement your own object table instead.

return(0);
If the object was not found, return a 0 value. This will cause the server to raise an exception (rpc_x_object_not_found).

The backing.idl file is compiled with the following ACF:

interface backing
{
[encode,decode] backing_data_convert(
[comm_status] st
);
}

The application must also declare the database conversion function as shown in the following backing.cxx file:

#include "backing.h"

extern "C" {



void backing_data_convert(
idl_es_handle_t h,
backing_data_s_t *data
) {
}

}

For more on how to use the backing store facility, see The DCE Backing Store.