1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
|
// File: excxx_example_database_read.cpp
#include <iostream>
#include <fstream>
#include <cstdlib>
#include "MyDb.hpp"
#include "gettingStartedCommon.hpp"
#ifdef _WIN32
extern "C" {
extern int getopt(int, char * const *, const char *);
extern char *optarg;
}
#else
#include <unistd.h>
#endif
// Forward declarations
int show_item(MyDb &itemnameSDB, MyDb &vendorDB, std::string &itemName);
int show_all_records(MyDb &inventoryDB, MyDb &vendorDB);
int show_vendor(MyDb &vendorDB, const char *vendor);
int
usage()
{
std::cout << "example_database_read [-i <path to data files>]"
<< " [-h <database home directory>]" << std::endl;
std::cout << "Note: Any path specified to the -h parameter must end"
<< " with your system's path delimiter (/ or \\)"
<< std::endl;
return (-1);
}
int
main (int argc, char *argv[])
{
char ch, lastChar;
// Initialize the path to the database files
std::string databaseHome("./");
std::string itemName;
// Database names
std::string vDbName("vendordb.db");
std::string iDbName("inventorydb.db");
std::string itemSDbName("itemname.sdb");
// Parse the command line arguments
while ((ch = getopt(argc, argv, "h:i:")) != EOF)
switch (ch) {
case 'h':
databaseHome = optarg;
lastChar = databaseHome[databaseHome.size() -1];
if (lastChar != '/' && lastChar != '\\')
return (usage());
break;
case 'i':
itemName = optarg;
break;
case '?':
default:
return (usage());
break;
}
try
{
// Open all databases.
MyDb inventoryDB(databaseHome, iDbName);
MyDb vendorDB(databaseHome, vDbName);
MyDb itemnameSDB(databaseHome, itemSDbName, true);
// Associate the secondary to the primary
inventoryDB.getDb().associate(NULL,
&(itemnameSDB.getDb()),
get_item_name,
0);
if (itemName.empty())
{
show_all_records(inventoryDB, vendorDB);
} else {
show_item(itemnameSDB, vendorDB, itemName);
}
} catch(DbException &e) {
std::cerr << "Error reading databases. " << std::endl;
return (e.get_errno());
} catch(std::exception &e) {
std::cerr << "Error reading databases. " << std::endl;
std::cerr << e.what() << std::endl;
return (-1);
}
return (0);
} // End main
// Shows the records in the inventory database that
// have a specific item name. For each inventory record
// shown, the appropriate vendor record is also displayed.
int
show_item(MyDb &itemnameSDB, MyDb &vendorDB, std::string &itemName)
{
// Get a cursor to the itemname secondary db
Dbc *cursorp;
try {
itemnameSDB.getDb().cursor(NULL, &cursorp, 0);
// Get the search key. This is the name on the inventory
// record that we want to examine.
std::cout << "Looking for " << itemName << std::endl;
Dbt key((void *)itemName.c_str(), (u_int32_t)itemName.length() + 1);
Dbt data;
// Position the cursor to the first record in the secondary
// database that has the appropriate key.
int ret = cursorp->get(&key, &data, DB_SET);
if (!ret) {
do {
InventoryData inventoryItem(data.get_data());
inventoryItem.show();
show_vendor(vendorDB, inventoryItem.getVendor().c_str());
} while (cursorp->get(&key, &data, DB_NEXT_DUP) == 0);
} else {
std::cerr << "No records found for '" << itemName
<< "'" << std::endl;
}
} catch(DbException &e) {
itemnameSDB.getDb().err(e.get_errno(), "Error in show_item");
cursorp->close();
throw e;
} catch(std::exception &e) {
itemnameSDB.getDb().errx("Error in show_item: %s", e.what());
cursorp->close();
throw e;
}
cursorp->close();
return (0);
}
// Shows all the records in the inventory database.
// For each inventory record shown, the appropriate
// vendor record is also displayed.
int
show_all_records(MyDb &inventoryDB, MyDb &vendorDB)
{
// Get a cursor to the inventory db
Dbc *cursorp;
try {
inventoryDB.getDb().cursor(NULL, &cursorp, 0);
// Iterate over the inventory database, from the first record
// to the last, displaying each in turn
Dbt key, data;
int ret;
while ((ret = cursorp->get(&key, &data, DB_NEXT)) == 0 )
{
InventoryData inventoryItem(data.get_data());
inventoryItem.show();
show_vendor(vendorDB, inventoryItem.getVendor().c_str());
}
} catch(DbException &e) {
inventoryDB.getDb().err(e.get_errno(), "Error in show_all_records");
cursorp->close();
throw e;
} catch(std::exception &e) {
cursorp->close();
throw e;
}
cursorp->close();
return (0);
}
// Shows a vendor record. Each vendor record is an instance of
// a vendor structure. See loadVendorDB() in
// example_database_load for how this structure was originally
// put into the database.
int
show_vendor(MyDb &vendorDB, const char *vendor)
{
Dbt data;
VENDOR my_vendor;
try {
// Set the search key to the vendor's name
// vendor is explicitly cast to char * to stop a compiler
// complaint.
Dbt key((char *)vendor, (u_int32_t)strlen(vendor) + 1);
// Make sure we use the memory we set aside for the VENDOR
// structure rather than the memory that DB allocates.
// Some systems may require structures to be aligned in memory
// in a specific way, and DB may not get it right.
data.set_data(&my_vendor);
data.set_ulen(sizeof(VENDOR));
data.set_flags(DB_DBT_USERMEM);
// Get the record
vendorDB.getDb().get(NULL, &key, &data, 0);
std::cout << " " << my_vendor.street << "\n"
<< " " << my_vendor.city << ", "
<< my_vendor.state << "\n"
<< " " << my_vendor.zipcode << "\n"
<< " " << my_vendor.phone_number << "\n"
<< " Contact: " << my_vendor.sales_rep << "\n"
<< " " << my_vendor.sales_rep_phone
<< std::endl;
} catch(DbException &e) {
vendorDB.getDb().err(e.get_errno(), "Error in show_vendor");
throw e;
} catch(std::exception &e) {
throw e;
}
return (0);
}
|