2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved.
7 #include "gettingstarted_common.h"
9 /* Forward declarations */
11 int load_vendors_database(STOCK_DBS, char *);
12 size_t pack_string(char *, char *, size_t);
13 int load_inventory_database(STOCK_DBS, char *);
18 fprintf(stderr, "example_database_load [-b <path to data files>]");
19 fprintf(stderr, " [-h <database_home_directory>]\n");
21 fprintf(stderr, "\tNote: Any path specified must end with your");
22 fprintf(stderr, " system's path delimiter (/ or \\)\n");
27 * Loads the contents of vendors.txt and inventory.txt into
28 * Berkeley DB databases. Also causes the itemname secondary
29 * database to be created and loaded.
32 main(int argc, char *argv[])
37 char *basename, *inventory_file, *vendor_file;
39 /* Initialize the STOCK_DBS struct */
40 initialize_stockdbs(&my_stock);
42 /* Initialize the base path. */
45 /* Parse the command line arguments */
46 while ((ch = getopt(argc, argv, "b:h:")) != EOF)
49 if (optarg[strlen(optarg)-1] != '/' &&
50 optarg[strlen(optarg)-1] != '\\')
52 my_stock.db_home_dir = optarg;
55 if (basename[strlen(basename)-1] != '/' &&
56 basename[strlen(basename)-1] != '\\')
65 /* Identify the files that will hold our databases */
66 set_db_filenames(&my_stock);
68 /* Find our input files */
69 size = strlen(basename) + strlen(INVENTORY_FILE) + 1;
70 inventory_file = malloc(size);
71 snprintf(inventory_file, size, "%s%s", basename, INVENTORY_FILE);
73 size = strlen(basename) + strlen(VENDORS_FILE) + 1;
74 vendor_file = malloc(size);
75 snprintf(vendor_file, size, "%s%s", basename, VENDORS_FILE);
77 /* Open all databases */
78 ret = databases_setup(&my_stock, "example_database_load", stderr);
80 fprintf(stderr, "Error opening databases\n");
81 databases_close(&my_stock);
85 ret = load_vendors_database(my_stock, vendor_file);
87 fprintf(stderr, "Error loading vendors database.\n");
88 databases_close(&my_stock);
91 ret = load_inventory_database(my_stock, inventory_file);
93 fprintf(stderr, "Error loading inventory database.\n");
94 databases_close(&my_stock);
98 /* close our environment and databases */
99 databases_close(&my_stock);
101 printf("Done loading databases.\n");
106 * Loads the contents of the vendors.txt file into
110 load_vendors_database(STOCK_DBS my_stock, char *vendor_file)
117 /* Load the vendors database */
118 ifp = fopen(vendor_file, "r");
120 fprintf(stderr, "Error opening file '%s'\n", vendor_file);
124 while (fgets(buf, MAXLINE, ifp) != NULL) {
125 /* zero out the structure */
126 memset(&my_vendor, 0, sizeof(VENDOR));
127 /* Zero out the DBTs */
128 memset(&key, 0, sizeof(DBT));
129 memset(&data, 0, sizeof(DBT));
132 * Scan the line into the structure.
133 * Convenient, but not particularly safe.
134 * In a real program, there would be a lot more
135 * defensive code here.
138 "%20[^#]#%20[^#]#%20[^#]#%3[^#]#%6[^#]#%13[^#]#%20[^#]#%20[^\n]",
139 my_vendor.name, my_vendor.street,
140 my_vendor.city, my_vendor.state,
141 my_vendor.zipcode, my_vendor.phone_number,
142 my_vendor.sales_rep, my_vendor.sales_rep_phone);
144 /* Now that we have our structure we can load it into the database. */
146 /* Set up the database record's key */
147 key.data = my_vendor.name;
148 key.size = (u_int32_t)strlen(my_vendor.name) + 1;
150 /* Set up the database record's data */
151 data.data = &my_vendor;
152 data.size = sizeof(VENDOR);
155 * Note that given the way we built our struct, there's extra
156 * bytes in it. Essentially we're using fixed-width fields with
157 * the unused portion of some fields padded with zeros. This
158 * is the easiest thing to do, but it does result in a bloated
159 * database. Look at load_inventory_data() for an example of how
163 /* Put the data into the database */
164 my_stock.vendor_dbp->put(my_stock.vendor_dbp, 0, &key, &data, 0);
165 } /* end vendors database while loop */
172 * Simple little convenience function that takes a buffer, a string,
173 * and an offset and copies that string into the buffer at the
174 * appropriate location. Used to ensure that all our strings
175 * are contained in a single contiguous chunk of memory.
178 pack_string(char *buffer, char *string, size_t start_pos)
182 string_size = strlen(string) + 1;
183 memcpy(buffer+start_pos, string, string_size);
185 return (start_pos + string_size);
189 * Loads the contents of the inventory.txt file into
190 * a database. Note that because the itemname
191 * secondary database is associated to the inventorydb
192 * (see env_setup() in gettingstarted_common.c), the
193 * itemname index is automatically created when this
194 * database is loaded.
197 load_inventory_database(STOCK_DBS my_stock, char *inventory_file)
201 char databuf[MAXDATABUF];
202 size_t bufLen, dataLen;
206 * Rather than lining everything up nicely in a struct, we're being
207 * deliberately a bit sloppy here. This function illustrates how to
208 * store mixed data that might be obtained from various locations
209 * in your application.
213 char category[MAXFIELD], name[MAXFIELD];
214 char vendor[MAXFIELD], sku[MAXFIELD];
216 /* Load the inventory database */
217 ifp = fopen(inventory_file, "r");
219 fprintf(stderr, "Error opening file '%s'\n", inventory_file);
223 while (fgets(buf, MAXLINE, ifp) != NULL) {
225 * Scan the line into the appropriate buffers and variables.
226 * Convenient, but not particularly safe. In a real
227 * program, there would be a lot more defensive code here.
230 "%20[^#]#%20[^#]#%f#%i#%20[^#]#%20[^\n]",
231 name, sku, &price, &quantity, category, vendor);
234 * Now pack it into a single contiguous memory location for
237 memset(databuf, 0, MAXDATABUF);
241 dataLen = sizeof(float);
242 memcpy(databuf, &price, dataLen);
245 dataLen = sizeof(int);
246 memcpy(databuf + bufLen, &quantity, dataLen);
249 bufLen = pack_string(databuf, name, bufLen);
250 bufLen = pack_string(databuf, sku, bufLen);
251 bufLen = pack_string(databuf, category, bufLen);
252 bufLen = pack_string(databuf, vendor, bufLen);
254 /* Zero out the DBTs */
255 memset(&key, 0, sizeof(DBT));
256 memset(&data, 0, sizeof(DBT));
258 /* The key is the item's SKU */
260 key.size = (u_int32_t)strlen(sku) + 1;
262 /* The data is the information that we packed into databuf. */
264 data.size = (u_int32_t)bufLen;
266 /* Put the data into the database */
267 my_stock.vendor_dbp->put(my_stock.inventory_dbp, 0, &key, &data, 0);
268 } /* end vendors database while loop */