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 9int get_item_name(DB *, const DBT *, const DBT *, DBT *); 10 11/* 12 * Used to extract an inventory item's name from an 13 * inventory database record. This function is used to create 14 * keys for secondary database records. 15 */ 16int 17get_item_name(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey) 18{ 19 u_int offset; 20 21 dbp = NULL; /* Not needed, unused. */ 22 pkey = NULL; 23 24 /* 25 * First, obtain the buffer location where we placed the 26 * item's name. In this example, the item's name is located 27 * in the primary data. It is the first string in the 28 * buffer after the price (a float) and the quantity (an int). 29 * 30 * See load_inventory_database() in example_database_load.c 31 * for how we packed the inventory information into the 32 * data DBT. 33 */ 34 offset = sizeof(float) + sizeof(int); 35 36 /* Check to make sure there's data */ 37 if (pdata->size < offset) 38 return (-1); /* Returning non-zero means that the 39 * secondary record is not created/updated. 40 */ 41 42 /* Now set the secondary key's data to be the item name */ 43 memset(skey, 0, sizeof(DBT)); 44 skey->data = (u_int8_t *)pdata->data + offset; 45 skey->size = (u_int32_t)strlen(skey->data) + 1; 46 47 return (0); 48} 49 50/* Opens a database */ 51int 52open_database(DB **dbpp, const char *file_name, 53 const char *program_name, FILE *error_file_pointer, 54 int is_secondary) 55{ 56 DB *dbp; /* For convenience */ 57 u_int32_t open_flags; 58 int ret; 59 60 /* Initialize the DB handle */ 61 ret = db_create(&dbp, NULL, 0); 62 if (ret != 0) { 63 fprintf(error_file_pointer, "%s: %s\n", program_name, 64 db_strerror(ret)); 65 return (ret); 66 } 67 /* Point to the memory malloc'd by db_create() */ 68 *dbpp = dbp; 69 70 /* Set up error handling for this database */ 71 dbp->set_errfile(dbp, error_file_pointer); 72 dbp->set_errpfx(dbp, program_name); 73 74 /* 75 * If this is a secondary database, then we want to allow 76 * sorted duplicates. 77 */ 78 if (is_secondary) { 79 ret = dbp->set_flags(dbp, DB_DUPSORT); 80 if (ret != 0) { 81 dbp->err(dbp, ret, "Attempt to set DUPSORT flags failed.", 82 file_name); 83 return (ret); 84 } 85 } 86 87 /* Set the open flags */ 88 open_flags = DB_CREATE; /* Allow database creation */ 89 90 /* Now open the database */ 91 ret = dbp->open(dbp, /* Pointer to the database */ 92 NULL, /* Txn pointer */ 93 file_name, /* File name */ 94 NULL, /* Logical db name */ 95 DB_BTREE, /* Database type (using btree) */ 96 open_flags, /* Open flags */ 97 0); /* File mode. Using defaults */ 98 if (ret != 0) { 99 dbp->err(dbp, ret, "Database '%s' open failed.", file_name); 100 return (ret); 101 } 102 103 return (0); 104} 105 106/* opens all databases */ 107int 108databases_setup(STOCK_DBS *my_stock, const char *program_name, 109 FILE *error_file_pointer) 110{ 111 int ret; 112 113 /* Open the vendor database */ 114 ret = open_database(&(my_stock->vendor_dbp), 115 my_stock->vendor_db_name, 116 program_name, error_file_pointer, 117 PRIMARY_DB); 118 if (ret != 0) 119 /* 120 * Error reporting is handled in open_database() so just return 121 * the return code. 122 */ 123 return (ret); 124 125 /* Open the inventory database */ 126 ret = open_database(&(my_stock->inventory_dbp), 127 my_stock->inventory_db_name, 128 program_name, error_file_pointer, 129 PRIMARY_DB); 130 if (ret != 0) 131 /* 132 * Error reporting is handled in open_database() so just return 133 * the return code. 134 */ 135 return (ret); 136 137 /* 138 * Open the itemname secondary database. This is used to 139 * index the product names found in the inventory 140 * database. 141 */ 142 ret = open_database(&(my_stock->itemname_sdbp), 143 my_stock->itemname_db_name, 144 program_name, error_file_pointer, 145 SECONDARY_DB); 146 if (ret != 0) 147 /* 148 * Error reporting is handled in open_database() so just return 149 * the return code. 150 */ 151 return (0); 152 153 /* 154 * Associate the itemname db with its primary db 155 * (inventory db). 156 */ 157 my_stock->inventory_dbp->associate( 158 my_stock->inventory_dbp, /* Primary db */ 159 NULL, /* txn id */ 160 my_stock->itemname_sdbp, /* Secondary db */ 161 get_item_name, /* Secondary key creator */ 162 0); /* Flags */ 163 164 printf("databases opened successfully\n"); 165 return (0); 166} 167 168/* Initializes the STOCK_DBS struct.*/ 169void 170initialize_stockdbs(STOCK_DBS *my_stock) 171{ 172 my_stock->db_home_dir = DEFAULT_HOMEDIR; 173 my_stock->inventory_dbp = NULL; 174 my_stock->vendor_dbp = NULL; 175 my_stock->itemname_sdbp = NULL; 176 my_stock->vendor_db_name = NULL; 177 my_stock->inventory_db_name = NULL; 178 my_stock->itemname_db_name = NULL; 179} 180 181/* Identify all the files that will hold our databases. */ 182void 183set_db_filenames(STOCK_DBS *my_stock) 184{ 185 size_t size; 186 187 /* Create the Inventory DB file name */ 188 size = strlen(my_stock->db_home_dir) + strlen(INVENTORYDB) + 1; 189 my_stock->inventory_db_name = malloc(size); 190 snprintf(my_stock->inventory_db_name, size, "%s%s", 191 my_stock->db_home_dir, INVENTORYDB); 192 193 /* Create the Vendor DB file name */ 194 size = strlen(my_stock->db_home_dir) + strlen(VENDORDB) + 1; 195 my_stock->vendor_db_name = malloc(size); 196 snprintf(my_stock->vendor_db_name, size, "%s%s", 197 my_stock->db_home_dir, VENDORDB); 198 199 /* Create the itemname DB file name */ 200 size = strlen(my_stock->db_home_dir) + strlen(ITEMNAMEDB) + 1; 201 my_stock->itemname_db_name = malloc(size); 202 snprintf(my_stock->itemname_db_name, size, "%s%s", 203 my_stock->db_home_dir, ITEMNAMEDB); 204 205} 206 207/* Closes all the databases and secondary databases. */ 208int 209databases_close(STOCK_DBS *my_stock) 210{ 211 int ret; 212 /* 213 * Note that closing a database automatically flushes its cached data 214 * to disk, so no sync is required here. 215 */ 216 if (my_stock->itemname_sdbp != NULL) { 217 ret = my_stock->itemname_sdbp->close(my_stock->itemname_sdbp, 0); 218 if (ret != 0) 219 fprintf(stderr, "Itemname database close failed: %s\n", 220 db_strerror(ret)); 221 } 222 223 if (my_stock->inventory_dbp != NULL) { 224 ret = my_stock->inventory_dbp->close(my_stock->inventory_dbp, 0); 225 if (ret != 0) 226 fprintf(stderr, "Inventory database close failed: %s\n", 227 db_strerror(ret)); 228 } 229 230 if (my_stock->vendor_dbp != NULL) { 231 ret = my_stock->vendor_dbp->close(my_stock->vendor_dbp, 0); 232 if (ret != 0) 233 fprintf(stderr, "Vendor database close failed: %s\n", 234 db_strerror(ret)); 235 } 236 237 printf("databases closed.\n"); 238 return (0); 239} 240