hamsterdb Embedded Database  2.1.7
env1.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2014 Christoph Rupp (chris@crupp.de).
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h> /* for exit() */
25 #include <ham/hamsterdb.h>
26 
27 void
28 error(const char *foo, ham_status_t st) {
29  printf("%s() returned error %d: %s\n", foo, st, ham_strerror(st));
30  exit(-1);
31 }
32 
33 #define MAX_DBS 2
34 
35 #define DBNAME_CUSTOMER 1
36 #define DBNAME_ORDER 2
37 
38 #define MAX_CUSTOMERS 4
39 #define MAX_ORDERS 8
40 
41 /* A structure for the "customer" database */
42 typedef struct {
43  ham_u32_t id; /* customer id */
44  char name[32]; /* customer name */
45  /* ... additional information could follow here */
46 } customer_t;
47 
48 /* A structure for the "orders" database */
49 typedef struct {
50  ham_u32_t id; /* order id */
51  ham_u32_t customer_id; /* customer id */
52  char assignee[32]; /* assigned to whom? */
53  /* ... additional information could follow here */
54 } order_t;
55 
56 int
57 main(int argc, char **argv) {
58  int i;
59  ham_status_t st; /* status variable */
60  ham_db_t *db[MAX_DBS]; /* hamsterdb database objects */
61  ham_env_t *env; /* hamsterdb environment */
62  ham_cursor_t *cursor[MAX_DBS]; /* a cursor for each database */
63 
64  ham_key_t key = {0};
65  ham_key_t cust_key = {0};
66  ham_key_t ord_key = {0};
67  ham_record_t record = {0};
68  ham_record_t cust_record = {0};
69  ham_record_t ord_record = {0};
70 
71  ham_parameter_t params[] = {
73  {0, }
74  };
75 
76  customer_t customers[MAX_CUSTOMERS] = {
77  { 1, "Alan Antonov Corp." },
78  { 2, "Barry Broke Inc." },
79  { 3, "Carl Caesar Lat." },
80  { 4, "Doris Dove Brd." }
81  };
82 
83  order_t orders[MAX_ORDERS] = {
84  { 1, 1, "Joe" },
85  { 2, 1, "Tom" },
86  { 3, 3, "Joe" },
87  { 4, 4, "Tom" },
88  { 5, 3, "Ben" },
89  { 6, 3, "Ben" },
90  { 7, 4, "Chris" },
91  { 8, 1, "Ben" }
92  };
93 
94  /* Now create a new hamsterdb Environment */
95  st = ham_env_create(&env, "test.db", 0, 0664, 0);
96  if (st != HAM_SUCCESS)
97  error("ham_env_create", st);
98 
99  /*
100  * Then create the two Databases in this Environment; each Database
101  * has a name - the first is our "customer" Database, the second
102  * is for the "orders"
103  *
104  * All database keys are uint32_t types.
105  */
106  st = ham_env_create_db(env, &db[0], DBNAME_CUSTOMER, 0, &params[0]);
107  if (st != HAM_SUCCESS)
108  error("ham_env_create_db (customer)", st);
109  st = ham_env_create_db(env, &db[1], DBNAME_ORDER, 0, &params[0]);
110  if (st != HAM_SUCCESS)
111  error("ham_env_create_db (order)", st);
112 
113  /* Create a Cursor for each Database */
114  for (i = 0; i < MAX_DBS; i++) {
115  st = ham_cursor_create(&cursor[i], db[i], 0, 0);
116  if (st != HAM_SUCCESS) {
117  printf("ham_cursor_create() failed with error %d\n", st);
118  return (-1);
119  }
120  }
121 
122  /* Insert a few customers in the first database */
123  for (i = 0; i < MAX_CUSTOMERS; i++) {
124  key.size = sizeof(int);
125  key.data = &customers[i].id;
126 
127  record.size = sizeof(customer_t);
128  record.data = &customers[i];
129 
130  st = ham_db_insert(db[0], 0, &key, &record, 0);
131  if (st != HAM_SUCCESS)
132  error("ham_db_insert (customer)", st);
133  }
134 
135  /* And now the orders in the second database */
136  for (i = 0; i < MAX_ORDERS; i++) {
137  key.size = sizeof(int);
138  key.data = &orders[i].id;
139 
140  record.size = sizeof(order_t);
141  record.data = &orders[i];
142 
143  st = ham_db_insert(db[1], 0, &key, &record, 0);
144  if (st != HAM_SUCCESS)
145  error("ham_db_insert (order)", st);
146  }
147 
148  /*
149  * To demonstrate even more functions: close all objects, then
150  * re-open the environment and the two databases.
151  *
152  * Note that ham_env_close automatically calls ham_db_close on all
153  * databases.
154  */
155  for (i = 0; i < MAX_DBS; i++) {
156  st = ham_cursor_close(cursor[i]);
157  if (st != HAM_SUCCESS)
158  error("ham_cursor_close", st);
159  }
160  st = ham_env_close(env, 0);
161  if (st != HAM_SUCCESS)
162  error("ham_env_close", st);
163 
164  /* Now reopen the environment and the databases */
165  st = ham_env_open(&env, "test.db", 0, 0);
166  if (st != HAM_SUCCESS)
167  error("ham_env_open", st);
168  st = ham_env_open_db(env, &db[0], DBNAME_CUSTOMER, 0, 0);
169  if (st != HAM_SUCCESS)
170  error("ham_env_open_db (customer)", st);
171  st = ham_env_open_db(env, &db[1], DBNAME_ORDER, 0, 0);
172  if (st != HAM_SUCCESS)
173  error("ham_env_open_db (order)", st);
174 
175  /* Re-create a cursor for each database */
176  for (i = 0; i < MAX_DBS; i++) {
177  st = ham_cursor_create(&cursor[i], db[i], 0, 0);
178  if (st != HAM_SUCCESS) {
179  printf("ham_cursor_create() failed with error %d\n", st);
180  return (-1);
181  }
182  }
183 
184  /*
185  * Now start the query - we want to dump each customer with his
186  * orders
187  *
188  * We have a loop with two cursors - the first cursor looping over
189  * the database with customers, the second loops over the orders.
190  */
191  while (1) {
192  customer_t *customer;
193 
194  st = ham_cursor_move(cursor[0], &cust_key, &cust_record,
196  if (st != HAM_SUCCESS) {
197  /* reached end of the database? */
198  if (st == HAM_KEY_NOT_FOUND)
199  break;
200  else
201  error("ham_cursor_next(customer)", st);
202  }
203 
204  customer = (customer_t *)cust_record.data;
205 
206  /* print the customer id and name */
207  printf("customer %d ('%s')\n", customer->id, customer->name);
208 
209  /*
210  * The inner loop prints all orders of this customer. Move the
211  * cursor to the first entry.
212  */
213  st = ham_cursor_move(cursor[1], &ord_key, &ord_record,
215  if (st != HAM_SUCCESS) {
216  /* reached end of the database? */
217  if (st == HAM_KEY_NOT_FOUND)
218  continue;
219  else
220  error("ham_cursor_next(order)", st);
221  }
222 
223  do {
224  order_t *order = (order_t *)ord_record.data;
225 
226  /* print this order, if it belongs to the current customer */
227  if (order->customer_id == customer->id)
228  printf(" order: %d (assigned to %s)\n",
229  order->id, order->assignee);
230 
231  st = ham_cursor_move(cursor[1], &ord_key,
232  &ord_record, HAM_CURSOR_NEXT);
233  if (st != HAM_SUCCESS) {
234  /* reached end of the database? */
235  if (st == HAM_KEY_NOT_FOUND)
236  break;
237  else
238  error("ham_cursor_next(order)", st);
239  }
240  } while (1);
241  }
242 
243  /*
244  * Now close the environment handle; the flag HAM_AUTO_CLEANUP will
245  * automatically close all databases and cursors
246  */
247  st = ham_env_close(env, HAM_AUTO_CLEANUP);
248  if (st != HAM_SUCCESS)
249  error("ham_env_close", st);
250 
251  printf("success!\n");
252  return (0);
253 }
254