Application-Level Data Caching
by Paul E. Boal

Listing One
typedef vector<string> StringList;
StringList q_fields = StringList(2); // Holds list of fields to query on
StringList q_types  = StringList(2); // Holds the data type of those fields
string *demo_key    = new string();  // String buffer for demo_key response
int ret;                             // Return value

q_fields[0] = GENDER;
q_fields[1] = AGE;
q_types[0]  = char;
q_types[1]  = int;

Lookup *demo = new Lookup (
        user:pass@dn:host,      // Database connect information
        DEMOGRAPHICS,           // Table name
        q_fields,               // Query field names
        q_types,                // Query field types
        DEMO_KEY,               // The expression to be returned
        Lookup::PrefetchQuery,  // Options
        True);                  // True so you do initialization right away
StringList values = StringList(2);      // Contains [0]=GENDER and [1]=AGE
ret = demo->Find(values, demo_key);
cerr << "Return code(" << ret <<"): When looking for ( 
<< values[0] << ,
<< values[1] << ) I found " << *s << endl;


Listing Two
typedef vector<string> StringList;

StringList q_fields = StringList(1);    // Holds list of fields to query on
StringList q_types  = StringList(1);    // Holds the data type of those fields
string *customer_key= new string();     // String buffer for demo_key response
int ret;                                // Return value

q_fields[0] = SSN;
q_types[0]  = char;

Lookup *cust = new Lookup (
        user:pass@dn:host,      // Database connect information
        CUSTOMERS,              // Table name
        q_fields,               // Query field names
        q_types,                // Query field types
        CUSTOMER_KEY,           // The expression to be returned
        Lookup::PrefetchQuery |
        Lookup::UseDiskCache,   // Options are logically OR'ed together
        False);                 // False so that we can change field lengths
// Set maximum length of query fields and maximum length of the response.
// Setting this to minimum posibble value helps save space in cache file
// and improve overall performance.
cust->SetQueryLength(10);
cust->SetResponseLength(10);

// Now that we've set the min query and response lengths, initialize and
// load the disk cache.
cust->Init();

// For our search, we'll loop through all 9-digit integers and find out how 
// many are a valid customer's SSN.
StringList values = StringList(1);
char ssn[10];
long found=0;

for (n=0; n<999999999; n++)
{
        sprintf (ssn, "%09d", n);
        values[0] = ssn;
        ret = demo->Find(values, customer_key);
        found += (ret==0?0:1);
}
cerr << "Found " << found << " valid SSN" << endl;


Listing Three
typedef vector<string> StringList;

StringList q_fields = StringList(2);    // Holds list of fields to query on
StringList q_types  = StringList(2);    // Holds the data type of those fields
string *demo_key    = new string();     // String buffer for demo_key response
int ret;                                // Return value

q_fields[0] = GENDER;
q_fields[1] = AGE;
q_types[0]  = char;
q_types[1]  = int;

Lookup *demo = new Lookup (
        user:pass@dn:host,      // Database connect information
        DEMOGRAPHICS,           // Table name
        q_fields,               // Query field names
        q_types,                // Query field types
        DEMO_KEY,               // The expression to be returned
        Lookup::DynamicQuery |
        Lookup::DynamicCache,   // Options
        True);                  // True so that you initialize right away
StringList values = StringList(2);  // Contains [0]=GENDER and [1]=AGE
for (int i=0; i<99; i++)
{
        ret = demo->Find(values, demo_key);
}
demo->PrintStats();


Listing Four
typedef vector<string> StringList;

StringList q_fields = StringList(2);    // Holds list of fields to query on
StringList q_types  = StringList(2);    // Holds the data type of those fields
string *ma_key = new string();          // String buffer for the response
int ret;                                // Return value

q_fields[0] = CITY;
q_fields[1] = STATE;
q_types[0]  = char;
q_types[1]  = char;

Lookup *demo = new Lookup (
        user:pass@dn:host,      // Database connect information
        METRO_AREA,             // Table name
        q_fields,               // Query field names
        q_types,                // Query field types
        METRO_AREA_KEY,         // The expression to be returned
        Lookup::DynamicQuery |
        Lookup::DynamicCache |
Lookup::DynamicAssign,  // Options
        True);          // True so that we do initialization right away
StringList values = StringList(2);      // Contains [0]=CITY and [1]=STATE
values[0] = "New City";
values[1] = "ZZ";
ret = demo->Find(values, ma_key);
demo->PrintStats();

Listing Five
create table METRO_AREA (
        METRO_AREA_KEY  int          not null auto_increment,
        CITY            varchar(30)  not null,
        STATE           char(2)      not null,
        REGION          varchar(20)      null,
        primary key (METRO_AREA_KEY)
);

Listing Six
typedef vector<string> StringList;
StringList q_fields = StringList(2);    // Holds list of fields to query on
StringList q_types  = StringList(2);    // Holds the data type of those fields
string *address = new string();         // String buffer for the response
int ret;                                // Return value

q_fields[0] = c.SSN;
q_fields[1] = a.ADDR_TYPE;
q_types[0]  = char;
q_types[1]  = char;

string sql_template = "
select &Q_FIELDS, &R_EXPRESSION 
from CUSTOMERS c, ADDRESSES a
where c.CUST_KEY = a.CUST_KEY
and &Q_CONDITIONS";

string r_expression = "
ADDR_LINE1 || '|' ||
ADDR_LINE2 || '|' ||
CITY       || '|' ||
STATE      || '|' ||
ZIP        || '|' ||
COUNTRY"

Lookup *demo = new Lookup (
        user:pass@dn:host,      // Database connect information
        sql_template,           // SQL Template
        q_fields,               // Query field names
        q_types,                // Query field types
        r_expression,           // The expression to be returned
        Lookup::DynamicQuery |
Lookup::UseTemplate,// Options
        True);             // True so that we do initialization right away
StringList values = StringList(2);      // Contains [0]=SSN and [1]=ADDR_TYPE
values[0] = "999115555";
values[1] = "HOME";
ret = demo->Find(values, address);
cerr << "Return code(" << ret <<"): When looking for ( 
<< values[0] << ,
<< values[1] << ) I found " << *address << endl;
// Then you can go off and parse the pipe-delimited address string 
// into it's components.

Listing Seven
// Get the region from the command line
string region = argv[0]; 

// And use that region to generate the SQL template for the Lookup
string sql_template = "
select &Q_FIELDS, &R_EXPRESSION
from CUSTOMERS
where REGION='" + region + "' and &Q_CONDITIONS";






4


