Implementing Key Extractors
Prev | Chapter 5. Secondary Databases | Next

## Implementing Key Extractors

You must provide every secondary database with a callback that creates keys from primary records. You identify this callback when you associate your secondary database to your primary.

You can create keys using whatever data you want. Typically you will base your key on some information found in a record's data, but you can also use information found in the primary record's key. How you build your keys is entirely dependent upon the nature of the index that you want to maintain.

You implement a key extractor by writing a function that extracts the necessary information from a primary record's key or data. This function must conform to a specific prototype, and it must be provided as a callback to the `associate()` method.

For example, suppose your primary database records contain data that uses the following structure:

    typedef struct vendor {
        char name[MAXFIELD];             /* Vendor name */
        char street[MAXFIELD];           /* Street name and number */
        char city[MAXFIELD];             /* City */
        char state[3];                   /* Two-digit US state code */
        char zipcode[6];                 /* US zipcode */
        char phone_number[13];           /* Vendor phone number */
        char sales_rep[MAXFIELD];        /* Name of sales representative */
        char sales_rep_phone[MAXFIELD];  /* Sales rep's phone number */
    } VENDOR;

Further suppose that you want to be able to query your primary database based on the name of a sales representative. Then you would write a function that looks like this:

    #include <db.h>

    ...

    int
    get_sales_rep(DB *sdbp,          /* secondary db handle */
                  const DBT *pkey,   /* primary db record's key */
                  const DBT *pdata,  /* primary db record's data */
                  DBT *skey)         /* secondary db record's key */
    {
        VENDOR *vendor;

        /* First, extract the structure contained in the primary's data */
        vendor = pdata->data;

        /* Now set the secondary key's data to be the representative's name */
        memset(skey, 0, sizeof(DBT));
        skey->data = vendor->sales_rep;
        skey->size = strlen(vendor->sales_rep) + 1;

        /* Return 0 to indicate that the record can be created/updated. */
        return (0);
    }

In order to use this function, you provide it on the `associate()` method after the primary and secondary databases have been created and opened:

    dbp->associate(dbp,            /* Primary database */
                   NULL,           /* TXN id */
                   sdbp,           /* Secondary database */
                   get_sales_rep,  /* Callback used for key creation. */
                   0);             /* Flags */

Prev | Up | Next
Chapter 5. Secondary Databases | Home | Reading Secondary Databases