• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/db-4.7.25.NC/examples_c/getting_started/
1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2004,2008 Oracle.  All rights reserved.
5 */
6
7#include "gettingstarted_common.h"
8
9/* Forward declarations */
10int usage(void);
11char *show_inventory_item(void *);
12int show_all_records(STOCK_DBS *);
13int show_records(STOCK_DBS *, char *);
14int show_vendor_record(char *, DB *);
15
16int
17usage()
18{
19    fprintf(stderr, "example_database_read [-i <item name>]");
20    fprintf(stderr, " [-h <database home>]\n");
21
22    fprintf(stderr,
23	"\tNote: Any path specified to the -h parameter must end\n");
24    fprintf(stderr, " with your system's path delimiter (/ or \\)\n");
25    return (-1);
26}
27
28/*
29 * Searches for a inventory item based on that item's name. The search is
30 * performed using the item name secondary database. Displays all
31 * inventory items that use the specified name, as well as the vendor
32 * associated with that inventory item.
33 *
34 * If no item name is provided, then all inventory items are displayed.
35 */
36int
37main(int argc, char *argv[])
38{
39    STOCK_DBS my_stock;
40    int ch, ret;
41    char *itemname;
42
43    /* Initialize the STOCK_DBS struct */
44    initialize_stockdbs(&my_stock);
45
46    /* Parse the command line arguments */
47    itemname = NULL;
48    while ((ch = getopt(argc, argv, "h:i:?")) != EOF)
49	switch (ch) {
50	case 'h':
51	    if (optarg[strlen(optarg)-1] != '/' &&
52		optarg[strlen(optarg)-1] != '\\')
53		return (usage());
54	    my_stock.db_home_dir = optarg;
55	    break;
56	case 'i':
57	    itemname = optarg;
58	    break;
59	case '?':
60	default:
61	    return (usage());
62	}
63
64    /* Identify the files that hold our databases */
65    set_db_filenames(&my_stock);
66
67    /* Open all databases */
68    ret = databases_setup(&my_stock, "example_database_read", stderr);
69    if (ret != 0) {
70	fprintf(stderr, "Error opening databases\n");
71	databases_close(&my_stock);
72	return (ret);
73    }
74
75    if (itemname == NULL)
76	ret = show_all_records(&my_stock);
77    else
78	ret = show_records(&my_stock, itemname);
79
80    /* close our databases */
81    databases_close(&my_stock);
82    return (ret);
83}
84
85int show_all_records(STOCK_DBS *my_stock)
86{
87    DBC *inventory_cursorp;
88    DBT key, data;
89    char *the_vendor;
90    int exit_value, ret;
91
92    /* Initialize our DBTs. */
93    memset(&key, 0, sizeof(DBT));
94    memset(&data, 0, sizeof(DBT));
95
96    /* Get a cursor to the inventory db */
97    my_stock->inventory_dbp->cursor(my_stock->inventory_dbp, NULL,
98      &inventory_cursorp, 0);
99
100    /*
101     * Iterate over the inventory database, from the first record
102     * to the last, displaying each in turn.
103     */
104    exit_value = 0;
105    while ((ret =
106      inventory_cursorp->get(inventory_cursorp, &key, &data, DB_NEXT)) == 0)
107    {
108	the_vendor = show_inventory_item(data.data);
109	ret = show_vendor_record(the_vendor, my_stock->vendor_dbp);
110	if (ret) {
111	    exit_value = ret;
112	    break;
113	}
114    }
115
116    /* Close the cursor */
117    inventory_cursorp->close(inventory_cursorp);
118    return (exit_value);
119}
120
121/*
122 * Search for an inventory item given its name (using the inventory item
123 * secondary database) and display that record and any duplicates that may
124 * exist.
125 */
126int
127show_records(STOCK_DBS *my_stock, char *itemname)
128{
129    DBC *itemname_cursorp;
130    DBT key, data;
131    char *the_vendor;
132    int ret, exit_value;
133
134    /* Initialize our DBTs. */
135    memset(&key, 0, sizeof(DBT));
136    memset(&data, 0, sizeof(DBT));
137
138    /* Get a cursor to the itemname db */
139    my_stock->itemname_sdbp->cursor(my_stock->itemname_sdbp, NULL,
140      &itemname_cursorp, 0);
141
142    /*
143     * Get the search key. This is the name on the inventory
144     * record that we want to examine.
145     */
146    key.data = itemname;
147    key.size = (u_int32_t)strlen(itemname) + 1;
148
149    /*
150     * Position our cursor to the first record in the secondary
151     * database that has the appropriate key.
152     */
153    exit_value = 0;
154    ret = itemname_cursorp->get(itemname_cursorp, &key, &data, DB_SET);
155    if (!ret) {
156	do {
157	    /*
158	     * Show the inventory record and the vendor responsible
159	     * for this inventory item.
160	     */
161	    the_vendor = show_inventory_item(data.data);
162	    ret = show_vendor_record(the_vendor, my_stock->vendor_dbp);
163	    if (ret) {
164		exit_value = ret;
165		break;
166	    }
167	    /*
168	     * Our secondary allows duplicates, so we need to loop over
169	     * the next duplicate records and show them all. This is done
170	     * because an inventory item's name is not a unique value.
171	     */
172	} while (itemname_cursorp->get(itemname_cursorp, &key, &data,
173	    DB_NEXT_DUP) == 0);
174    } else {
175	printf("No records found for '%s'\n", itemname);
176    }
177
178    /* Close the cursor */
179    itemname_cursorp->close(itemname_cursorp);
180
181    return (exit_value);
182}
183
184/*
185 * Shows an inventory item. How we retrieve the inventory
186 * item values from the provided buffer is strictly dependent
187 * on the order that those items were originally stored in the
188 * DBT. See load_inventory_database in example_database_load
189 * for how this was done.
190 */
191char *
192show_inventory_item(void *vBuf)
193{
194    float price;
195    int quantity;
196    size_t buf_pos;
197    char *category, *name, *sku, *vendor_name;
198    char *buf = (char *)vBuf;
199
200    price = *((float *)buf);
201    buf_pos = sizeof(float);
202
203    quantity = *((int *)(buf + buf_pos));
204    buf_pos += sizeof(int);
205
206    name = buf + buf_pos;
207    buf_pos += strlen(name) + 1;
208
209    sku = buf + buf_pos;
210    buf_pos += strlen(sku) + 1;
211
212    category = buf + buf_pos;
213    buf_pos += strlen(category) + 1;
214
215    vendor_name = buf + buf_pos;
216
217    printf("name: %s\n", name);
218    printf("\tSKU: %s\n", sku);
219    printf("\tCategory: %s\n", category);
220    printf("\tPrice: %.2f\n", price);
221    printf("\tQuantity: %i\n", quantity);
222    printf("\tVendor:\n");
223
224    return (vendor_name);
225}
226
227/*
228 * Shows a vendor record. Each vendor record is an instance of
229 * a vendor structure. See load_vendor_database() in
230 * example_database_load for how this structure was originally
231 * put into the database.
232 */
233int
234show_vendor_record(char *vendor_name, DB *vendor_dbp)
235{
236    DBT key, data;
237    VENDOR my_vendor;
238    int ret;
239
240    /* Zero our DBTs */
241    memset(&key, 0, sizeof(DBT));
242    memset(&data, 0, sizeof(DBT));
243
244    /* Set the search key to the vendor's name */
245    key.data = vendor_name;
246    key.size = (u_int32_t)strlen(vendor_name) + 1;
247
248    /*
249     * Make sure we use the memory we set aside for the VENDOR
250     * structure rather than the memory that DB allocates.
251     * Some systems may require structures to be aligned in memory
252     * in a specific way, and DB may not get it right.
253     */
254
255    data.data = &my_vendor;
256    data.ulen = sizeof(VENDOR);
257    data.flags = DB_DBT_USERMEM;
258
259    /* Get the record */
260    ret = vendor_dbp->get(vendor_dbp, NULL, &key, &data, 0);
261    if (ret != 0) {
262	vendor_dbp->err(vendor_dbp, ret, "Error searching for vendor: '%s'",
263	  vendor_name);
264	return (ret);
265    } else {
266	printf("\t\t%s\n", my_vendor.name);
267	printf("\t\t%s\n", my_vendor.street);
268	printf("\t\t%s, %s\n", my_vendor.city, my_vendor.state);
269	printf("\t\t%s\n\n", my_vendor.zipcode);
270	printf("\t\t%s\n\n", my_vendor.phone_number);
271	printf("\t\tContact: %s\n", my_vendor.sales_rep);
272	printf("\t\t%s\n", my_vendor.sales_rep_phone);
273    }
274    return (0);
275}
276