Imported Upstream version 5.3.21
[platform/upstream/libdb.git] / examples / c / getting_started / gettingstarted_common.c
1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2004, 2012 Oracle and/or its affiliates.  All rights reserved.
5  */
6
7 #include "gettingstarted_common.h"
8
9 int 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  */
16 int
17 get_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 */
51 int
52 open_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 */
107 int
108 databases_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 (ret);
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.*/
169 void
170 initialize_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. */
182 void
183 set_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. */
208 int
209 databases_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 }