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

example_database_read.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 2004-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  */
00007 
00008 #include "gettingstarted_common.h"
00009 
00010 /* Forward declarations */
00011 int usage(void);
00012 char *show_inventory_item(void *);
00013 int show_all_records(STOCK_DBS *);
00014 int show_records(STOCK_DBS *, char *);
00015 int show_vendor_record(char *, DB *);
00016 
00017 int
00018 usage()
00019 {
00020     fprintf(stderr, "example_database_read [-i <item name>]");
00021     fprintf(stderr, " [-h <database home>]\n");
00022 
00023     fprintf(stderr,
00024         "\tNote: Any path specified to the -h parameter must end\n");
00025     fprintf(stderr, " with your system's path delimiter (/ or \\)\n");
00026     return (-1);
00027 }
00028 
00029 /*
00030  * Searches for a inventory item based on that item's name. The search is
00031  * performed using the item name secondary database. Displays all
00032  * inventory items that use the specified name, as well as the vendor
00033  * associated with that inventory item.
00034  *
00035  * If no item name is provided, then all inventory items are displayed.
00036  */
00037 int
00038 main(int argc, char *argv[])
00039 {
00040     STOCK_DBS my_stock;
00041     int ch, ret;
00042     char *itemname;
00043 
00044     /* Initialize the STOCK_DBS struct */
00045     initialize_stockdbs(&my_stock);
00046 
00047     /* Parse the command line arguments */
00048     itemname = NULL;
00049     while ((ch = getopt(argc, argv, "h:i:?")) != EOF)
00050         switch (ch) {
00051         case 'h':
00052             if (optarg[strlen(optarg)-1] != '/' &&
00053                 optarg[strlen(optarg)-1] != '\\')
00054                 return (usage());
00055             my_stock.db_home_dir = optarg;
00056             break;
00057         case 'i':
00058             itemname = optarg;
00059             break;
00060         case '?':
00061         default:
00062             return (usage());
00063         }
00064 
00065     /* Identify the files that hold our databases */
00066     set_db_filenames(&my_stock);
00067 
00068     /* Open all databases */
00069     ret = databases_setup(&my_stock, "example_database_read", stderr);
00070     if (ret != 0) {
00071         fprintf(stderr, "Error opening databases\n");
00072         databases_close(&my_stock);
00073         return (ret);
00074     }
00075 
00076     if (itemname == NULL)
00077         ret = show_all_records(&my_stock);
00078     else
00079         ret = show_records(&my_stock, itemname);
00080 
00081     /* close our databases */
00082     databases_close(&my_stock);
00083     return (ret);
00084 }
00085 
00086 int show_all_records(STOCK_DBS *my_stock)
00087 {
00088     DBC *inventory_cursorp;
00089     DBT key, data;
00090     char *the_vendor;
00091     int exit_value, ret;
00092 
00093     /* Initialize our DBTs. */
00094     memset(&key, 0, sizeof(DBT));
00095     memset(&data, 0, sizeof(DBT));
00096 
00097     /* Get a cursor to the inventory db */
00098     my_stock->inventory_dbp->cursor(my_stock->inventory_dbp, NULL,
00099       &inventory_cursorp, 0);
00100 
00101     /*
00102      * Iterate over the inventory database, from the first record
00103      * to the last, displaying each in turn.
00104      */
00105     exit_value = 0;
00106     while ((ret =
00107       inventory_cursorp->c_get(inventory_cursorp, &key, &data, DB_NEXT)) == 0)
00108     {
00109         the_vendor = show_inventory_item(data.data);
00110         ret = show_vendor_record(the_vendor, my_stock->vendor_dbp);
00111         if (ret) {
00112             exit_value = ret;
00113             break;
00114         }
00115     }
00116 
00117     /* Close the cursor */
00118     inventory_cursorp->c_close(inventory_cursorp);
00119     return (exit_value);
00120 }
00121 
00122 /*
00123  * Search for an inventory item given its name (using the inventory item
00124  * secondary database) and display that record and any duplicates that may
00125  * exist.
00126  */
00127 int
00128 show_records(STOCK_DBS *my_stock, char *itemname)
00129 {
00130     DBC *itemname_cursorp;
00131     DBT key, data;
00132     char *the_vendor;
00133     int ret, exit_value;
00134 
00135     /* Initialize our DBTs. */
00136     memset(&key, 0, sizeof(DBT));
00137     memset(&data, 0, sizeof(DBT));
00138 
00139     /* Get a cursor to the itemname db */
00140     my_stock->itemname_sdbp->cursor(my_stock->itemname_sdbp, NULL,
00141       &itemname_cursorp, 0);
00142 
00143     /*
00144      * Get the search key. This is the name on the inventory
00145      * record that we want to examine.
00146      */
00147     key.data = itemname;
00148     key.size = (u_int32_t)strlen(itemname) + 1;
00149 
00150     /*
00151      * Position our cursor to the first record in the secondary
00152      * database that has the appropriate key.
00153      */
00154     exit_value = 0;
00155     ret = itemname_cursorp->c_get(itemname_cursorp, &key, &data, DB_SET);
00156     if (!ret) {
00157         do {
00158             /*
00159              * Show the inventory record and the vendor responsible
00160              * for this inventory item.
00161              */
00162             the_vendor = show_inventory_item(data.data);
00163             ret = show_vendor_record(the_vendor, my_stock->vendor_dbp);
00164             if (ret) {
00165                 exit_value = ret;
00166                 break;
00167             }
00168             /*
00169              * Our secondary allows duplicates, so we need to loop over
00170              * the next duplicate records and show them all. This is done
00171              * because an inventory item's name is not a unique value.
00172              */
00173         } while (itemname_cursorp->c_get(itemname_cursorp, &key, &data,
00174             DB_NEXT_DUP) == 0);
00175     } else {
00176         printf("No records found for '%s'\n", itemname);
00177     }
00178 
00179     /* Close the cursor */
00180     itemname_cursorp->c_close(itemname_cursorp);
00181 
00182     return (exit_value);
00183 }
00184 
00185 /*
00186  * Shows an inventory item. How we retrieve the inventory
00187  * item values from the provided buffer is strictly dependent
00188  * on the order that those items were originally stored in the
00189  * DBT. See load_inventory_database in example_database_load
00190  * for how this was done.
00191  */
00192 char *
00193 show_inventory_item(void *vBuf)
00194 {
00195     float price;
00196     int quantity;
00197     size_t buf_pos;
00198     char *category, *name, *sku, *vendor_name;
00199     char *buf = (char *)vBuf;
00200 
00201     price = *((float *)buf);
00202     buf_pos = sizeof(float);
00203 
00204     quantity = *((int *)(buf + buf_pos));
00205     buf_pos += sizeof(int);
00206 
00207     name = buf + buf_pos;
00208     buf_pos += strlen(name) + 1;
00209 
00210     sku = buf + buf_pos;
00211     buf_pos += strlen(sku) + 1;
00212 
00213     category = buf + buf_pos;
00214     buf_pos += strlen(category) + 1;
00215 
00216     vendor_name = buf + buf_pos;
00217 
00218     printf("name: %s\n", name);
00219     printf("\tSKU: %s\n", sku);
00220     printf("\tCategory: %s\n", category);
00221     printf("\tPrice: %.2f\n", price);
00222     printf("\tQuantity: %i\n", quantity);
00223     printf("\tVendor:\n");
00224 
00225     return (vendor_name);
00226 }
00227 
00228 /*
00229  * Shows a vendor record. Each vendor record is an instance of
00230  * a vendor structure. See load_vendor_database() in
00231  * example_database_load for how this structure was originally
00232  * put into the database.
00233  */
00234 int
00235 show_vendor_record(char *vendor_name, DB *vendor_dbp)
00236 {
00237     DBT key, data;
00238     VENDOR my_vendor;
00239     int ret;
00240 
00241     /* Zero our DBTs */
00242     memset(&key, 0, sizeof(DBT));
00243     memset(&data, 0, sizeof(DBT));
00244 
00245     /* Set the search key to the vendor's name */
00246     key.data = vendor_name;
00247     key.size = (u_int32_t)strlen(vendor_name) + 1;
00248 
00249     /*
00250      * Make sure we use the memory we set aside for the VENDOR
00251      * structure rather than the memory that DB allocates.
00252      * Some systems may require structures to be aligned in memory
00253      * in a specific way, and DB may not get it right.
00254      */
00255 
00256     data.data = &my_vendor;
00257     data.ulen = sizeof(VENDOR);
00258     data.flags = DB_DBT_USERMEM;
00259 
00260     /* Get the record */
00261     ret = vendor_dbp->get(vendor_dbp, NULL, &key, &data, 0);
00262     if (ret != 0) {
00263         vendor_dbp->err(vendor_dbp, ret, "Error searching for vendor: '%s'",
00264           vendor_name);
00265         return (ret);
00266     } else {
00267         printf("\t\t%s\n", my_vendor.name);
00268         printf("\t\t%s\n", my_vendor.street);
00269         printf("\t\t%s, %s\n", my_vendor.city, my_vendor.state);
00270         printf("\t\t%s\n\n", my_vendor.zipcode);
00271         printf("\t\t%s\n\n", my_vendor.phone_number);
00272         printf("\t\tContact: %s\n", my_vendor.sales_rep);
00273         printf("\t\t%s\n", my_vendor.sales_rep_phone);
00274     }
00275     return (0);
00276 }

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