Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

excxx_example_database_read.cpp

00001 // File: excxx_example_database_read.cpp
00002 
00003 #include <iostream>
00004 #include <fstream>
00005 #include <cstdlib>
00006 
00007 #include "MyDb.hpp"
00008 #include "gettingStartedCommon.hpp"
00009 
00010 #ifdef _WIN32
00011 extern "C" {
00012   extern int getopt(int, char * const *, const char *);
00013   extern char *optarg;
00014 }
00015 #else
00016 #include <unistd.h>
00017 #endif
00018 
00019 // Forward declarations
00020 int show_item(MyDb &itemnameSDB, MyDb &vendorDB, std::string &itemName);
00021 int show_all_records(MyDb &inventoryDB, MyDb &vendorDB);
00022 int show_vendor(MyDb &vendorDB, const char *vendor);
00023 
00024 int
00025 usage()
00026 {
00027     std::cout << "example_database_read [-i <path to data files>]"
00028               << " [-h <database home directory>]" << std::endl;
00029 
00030     std::cout << "Note: Any path specified to the -h parameter must end"
00031               << " with your system's path delimiter (/ or \\)"
00032               << std::endl;
00033     return (-1);
00034 }
00035 
00036 int
00037 main (int argc, char *argv[])
00038 {
00039 
00040    char ch, lastChar;
00041 
00042    // Initialize the path to the database files
00043    std::string databaseHome("./");
00044    std::string itemName;
00045 
00046    // Database names
00047    std::string vDbName("vendordb.db");
00048    std::string iDbName("inventorydb.db");
00049    std::string itemSDbName("itemname.sdb");
00050 
00051     // Parse the command line arguments
00052     while ((ch = getopt(argc, argv, "h:i:")) != EOF)
00053         switch (ch) {
00054         case 'h':
00055             databaseHome = optarg;
00056             lastChar = databaseHome[databaseHome.size() -1];
00057             if (lastChar != '/' && lastChar != '\\')
00058                 return (usage());
00059             break;
00060         case 'i':
00061             itemName = optarg;
00062             break;
00063         case '?':
00064         default:
00065             return (usage());
00066             break;
00067         }
00068 
00069     try
00070     {
00071         // Open all databases.
00072         MyDb inventoryDB(databaseHome, iDbName);
00073         MyDb vendorDB(databaseHome, vDbName);
00074         MyDb itemnameSDB(databaseHome, itemSDbName, true);
00075 
00076         // Associate the secondary to the primary
00077         inventoryDB.getDb().associate(NULL,
00078                                       &(itemnameSDB.getDb()),
00079                                       get_item_name,
00080                                       0);
00081 
00082         if (itemName.empty())
00083         {
00084             show_all_records(inventoryDB, vendorDB);
00085         } else {
00086             show_item(itemnameSDB, vendorDB, itemName);
00087         }
00088     } catch(DbException &e) {
00089         std::cerr << "Error reading databases. " << std::endl;
00090         return (e.get_errno());
00091     } catch(std::exception &e) {
00092         std::cerr << "Error reading databases. " << std::endl;
00093         std::cerr << e.what() << std::endl;
00094         return (-1);
00095     }
00096 
00097     return (0);
00098 } // End main
00099 
00100 // Shows the records in the inventory database that
00101 // have a specific item name. For each inventory record
00102 // shown, the appropriate vendor record is also displayed.
00103 int
00104 show_item(MyDb &itemnameSDB, MyDb &vendorDB, std::string &itemName)
00105 {
00106 
00107     // Get a cursor to the itemname secondary db
00108     Dbc *cursorp;
00109 
00110     try {
00111         itemnameSDB.getDb().cursor(NULL, &cursorp, 0);
00112 
00113         // Get the search key. This is the name on the inventory
00114         // record that we want to examine.
00115         std::cout << "Looking for " << itemName << std::endl;
00116         Dbt key((void *)itemName.c_str(), (u_int32_t)itemName.length() + 1);
00117         Dbt data;
00118 
00119         // Position the cursor to the first record in the secondary
00120         // database that has the appropriate key.
00121         int ret = cursorp->get(&key, &data, DB_SET);
00122         if (!ret) {
00123             do {
00124                 InventoryData inventoryItem(data.get_data());
00125                 inventoryItem.show();
00126 
00127                 show_vendor(vendorDB, inventoryItem.getVendor().c_str());
00128 
00129             } while (cursorp->get(&key, &data, DB_NEXT_DUP) == 0);
00130         } else {
00131             std::cerr << "No records found for '" << itemName
00132                     << "'" << std::endl;
00133         }
00134     } catch(DbException &e) {
00135         itemnameSDB.getDb().err(e.get_errno(), "Error in show_item");
00136         cursorp->close();
00137         throw e;
00138     } catch(std::exception &e) {
00139         itemnameSDB.getDb().errx("Error in show_item: %s", e.what());
00140         cursorp->close();
00141         throw e;
00142     }
00143 
00144     cursorp->close();
00145     return (0);
00146 }
00147 
00148 // Shows all the records in the inventory database.
00149 // For each inventory record shown, the appropriate
00150 // vendor record is also displayed.
00151 int
00152 show_all_records(MyDb &inventoryDB, MyDb &vendorDB)
00153 {
00154 
00155     // Get a cursor to the inventory db
00156     Dbc *cursorp;
00157     try {
00158         inventoryDB.getDb().cursor(NULL, &cursorp, 0);
00159 
00160         // Iterate over the inventory database, from the first record
00161         // to the last, displaying each in turn
00162         Dbt key, data;
00163         int ret;
00164         while ((ret = cursorp->get(&key, &data, DB_NEXT)) == 0 )
00165         {
00166             InventoryData inventoryItem(data.get_data());
00167             inventoryItem.show();
00168 
00169             show_vendor(vendorDB, inventoryItem.getVendor().c_str());
00170         }
00171     } catch(DbException &e) {
00172         inventoryDB.getDb().err(e.get_errno(), "Error in show_all_records");
00173         cursorp->close();
00174         throw e;
00175     } catch(std::exception &e) {
00176         cursorp->close();
00177         throw e;
00178     }
00179 
00180     cursorp->close();
00181     return (0);
00182 }
00183 
00184 // Shows a vendor record. Each vendor record is an instance of
00185 // a vendor structure. See loadVendorDB() in
00186 // example_database_load for how this structure was originally
00187 // put into the database.
00188 int
00189 show_vendor(MyDb &vendorDB, const char *vendor)
00190 {
00191     Dbt data;
00192     VENDOR my_vendor;
00193 
00194     try {
00195         // Set the search key to the vendor's name
00196         // vendor is explicitly cast to char * to stop a compiler
00197         // complaint.
00198         Dbt key((char *)vendor, (u_int32_t)strlen(vendor) + 1);
00199 
00200         // Make sure we use the memory we set aside for the VENDOR
00201         // structure rather than the memory that DB allocates.
00202         // Some systems may require structures to be aligned in memory
00203         // in a specific way, and DB may not get it right.
00204 
00205         data.set_data(&my_vendor);
00206         data.set_ulen(sizeof(VENDOR));
00207         data.set_flags(DB_DBT_USERMEM);
00208 
00209         // Get the record
00210         vendorDB.getDb().get(NULL, &key, &data, 0);
00211         std::cout << "        " << my_vendor.street << "\n"
00212                   << "        " << my_vendor.city << ", "
00213                   << my_vendor.state << "\n"
00214                   << "        " << my_vendor.zipcode << "\n"
00215                   << "        " << my_vendor.phone_number << "\n"
00216                   << "        Contact: " << my_vendor.sales_rep << "\n"
00217                   << "                 " << my_vendor.sales_rep_phone
00218                   << std::endl;
00219 
00220     } catch(DbException &e) {
00221         vendorDB.getDb().err(e.get_errno(), "Error in show_vendor");
00222         throw e;
00223     } catch(std::exception &e) {
00224         throw e;
00225     }
00226     return (0);
00227 }

Generated on Sun Dec 25 12:14:25 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2