hamsterdb Embedded Database  2.1.1
env1.c
Go to the documentation of this file.
00001 
00016 #include <stdio.h>
00017 #include <string.h>
00018 #include <stdlib.h> /* for exit() */
00019 #include <ham/hamsterdb.h>
00020 
00021 void
00022 error(const char *foo, ham_status_t st) {
00023   printf("%s() returned error %d: %s\n", foo, st, ham_strerror(st));
00024   exit(-1);
00025 }
00026 
00027 #define MAX_DBS           2
00028 
00029 #define DBNAME_CUSTOMER   1
00030 #define DBNAME_ORDER      2
00031 
00032 #define MAX_CUSTOMERS     4
00033 #define MAX_ORDERS        8
00034 
00035 /* A structure for the "customer" database */
00036 typedef struct {
00037   int id;         /* customer id */
00038   char name[32];      /* customer name */
00039   /* ... additional information could follow here */
00040 } customer_t;
00041 
00042 /* A structure for the "orders" database */
00043 typedef struct {
00044   int id;         /* order id */
00045   int customer_id;    /* customer id */
00046   char assignee[32];    /* assigned to whom? */
00047   /* ... additional information could follow here */
00048 } order_t;
00049 
00050 int
00051 main(int argc, char **argv) {
00052   int i;
00053   ham_status_t st;    /* status variable */
00054   ham_db_t *db[MAX_DBS];  /* hamsterdb database objects */
00055   ham_env_t *env;     /* hamsterdb environment */
00056   ham_cursor_t *cursor[MAX_DBS]; /* a cursor for each database */
00057   ham_key_t key, cust_key, ord_key;
00058   ham_record_t record, cust_record, ord_record;
00059 
00060   customer_t customers[MAX_CUSTOMERS] = {
00061     { 1, "Alan Antonov Corp." },
00062     { 2, "Barry Broke Inc." },
00063     { 3, "Carl Caesar Lat." },
00064     { 4, "Doris Dove Brd." }
00065   };
00066 
00067   order_t orders[MAX_ORDERS] = {
00068     { 1, 1, "Joe" },
00069     { 2, 1, "Tom" },
00070     { 3, 3, "Joe" },
00071     { 4, 4, "Tom" },
00072     { 5, 3, "Ben" },
00073     { 6, 3, "Ben" },
00074     { 7, 4, "Chris" },
00075     { 8, 1, "Ben" }
00076   };
00077 
00078   memset(&key, 0, sizeof(key));
00079   memset(&record, 0, sizeof(record));
00080   memset(&cust_key, 0, sizeof(cust_key));
00081   memset(&cust_record, 0, sizeof(cust_record));
00082   memset(&ord_key, 0, sizeof(ord_key));
00083   memset(&ord_record, 0, sizeof(ord_record));
00084 
00085   /* Now create a new hamsterdb Environment */
00086   st = ham_env_create(&env, "test.db", 0, 0664, 0);
00087   if (st != HAM_SUCCESS)
00088     error("ham_env_create", st);
00089 
00090   /*
00091    * Then create the two Databases in this Environment; each Database
00092    * has a name - the first is our "customer" Database, the second
00093    * is for the "orders"
00094    */
00095   st = ham_env_create_db(env, &db[0], DBNAME_CUSTOMER, 0, 0);
00096   if (st != HAM_SUCCESS)
00097     error("ham_env_create_db (customer)", st);
00098   st = ham_env_create_db(env, &db[1], DBNAME_ORDER, 0, 0);
00099   if (st != HAM_SUCCESS)
00100     error("ham_env_create_db (order)", st);
00101 
00102   /* Create a Cursor for each Database */
00103   for (i = 0; i < MAX_DBS; i++) {
00104     st = ham_cursor_create(&cursor[i], db[i], 0, 0);
00105     if (st != HAM_SUCCESS) {
00106       printf("ham_cursor_create() failed with error %d\n", st);
00107       return (-1);
00108     }
00109   }
00110 
00111   /* Insert a few customers in the first database */
00112   for (i = 0; i < MAX_CUSTOMERS; i++) {
00113     key.size = sizeof(int);
00114     key.data = &customers[i].id;
00115 
00116     record.size = sizeof(customer_t);
00117     record.data = &customers[i];
00118 
00119     st = ham_db_insert(db[0], 0, &key, &record, 0);
00120     if (st != HAM_SUCCESS)
00121       error("ham_db_insert (customer)", st);
00122   }
00123 
00124   /* And now the orders in the second database */
00125   for (i = 0; i < MAX_ORDERS; i++) {
00126     key.size = sizeof(int);
00127     key.data = &orders[i].id;
00128 
00129     record.size = sizeof(order_t);
00130     record.data = &orders[i];
00131 
00132     st = ham_db_insert(db[1], 0, &key, &record, 0);
00133     if (st != HAM_SUCCESS)
00134       error("ham_db_insert (order)", st);
00135   }
00136 
00137   /*
00138    * To demonstrate even more functions: close all objects, then
00139    * re-open the environment and the two databases.
00140    *
00141    * Note that ham_env_close automatically calls ham_db_close on all
00142    * databases.
00143    */
00144   for (i = 0; i < MAX_DBS; i++) {
00145     st = ham_cursor_close(cursor[i]);
00146     if (st != HAM_SUCCESS)
00147       error("ham_cursor_close", st);
00148   }
00149   st = ham_env_close(env, 0);
00150   if (st != HAM_SUCCESS)
00151     error("ham_env_close", st);
00152 
00153   /* Now reopen the environment and the databases */
00154   st = ham_env_open(&env, "test.db", 0, 0);
00155   if (st != HAM_SUCCESS)
00156     error("ham_env_open", st);
00157   st = ham_env_open_db(env, &db[0], DBNAME_CUSTOMER, 0, 0);
00158   if (st != HAM_SUCCESS)
00159     error("ham_env_open_db (customer)", st);
00160   st = ham_env_open_db(env, &db[1], DBNAME_ORDER, 0, 0);
00161   if (st != HAM_SUCCESS)
00162     error("ham_env_open_db (order)", st);
00163 
00164   /* Re-create a cursor for each database */
00165   for (i = 0; i < MAX_DBS; i++) {
00166     st = ham_cursor_create(&cursor[i], db[i], 0, 0);
00167     if (st != HAM_SUCCESS) {
00168       printf("ham_cursor_create() failed with error %d\n", st);
00169       return (-1);
00170     }
00171   }
00172 
00173   /*
00174    * Now start the query - we want to dump each customer with his
00175    * orders
00176    *
00177    * We have a loop with two cursors - the first cursor looping over
00178    * the database with customers, the second loops over the orders.
00179    */
00180   while (1) {
00181     customer_t *customer;
00182 
00183     st = ham_cursor_move(cursor[0], &cust_key, &cust_record,
00184             HAM_CURSOR_NEXT);
00185     if (st != HAM_SUCCESS) {
00186       /* reached end of the database? */
00187       if (st == HAM_KEY_NOT_FOUND)
00188         break;
00189       else
00190         error("ham_cursor_next(customer)", st);
00191     }
00192 
00193     customer = (customer_t *)cust_record.data;
00194 
00195     /* print the customer id and name */
00196     printf("customer %d ('%s')\n", customer->id, customer->name);
00197 
00198     /*
00199      * The inner loop prints all orders of this customer. Move the
00200      * cursor to the first entry.
00201      */
00202     st = ham_cursor_move(cursor[1], &ord_key, &ord_record,
00203             HAM_CURSOR_FIRST);
00204     if (st != HAM_SUCCESS) {
00205       /* reached end of the database? */
00206       if (st == HAM_KEY_NOT_FOUND)
00207         continue;
00208       else
00209         error("ham_cursor_next(order)", st);
00210     }
00211 
00212     do {
00213       order_t *order = (order_t *)ord_record.data;
00214 
00215       /* print this order, if it belongs to the current customer */
00216       if (order->customer_id == customer->id)
00217         printf("  order: %d (assigned to %s)\n",
00218             order->id, order->assignee);
00219 
00220       st = ham_cursor_move(cursor[1], &ord_key,
00221           &ord_record, HAM_CURSOR_NEXT);
00222       if (st != HAM_SUCCESS) {
00223         /* reached end of the database? */
00224         if (st == HAM_KEY_NOT_FOUND)
00225           break;
00226         else
00227           error("ham_cursor_next(order)", st);
00228       }
00229     } while (1);
00230   }
00231 
00232   /*
00233    * Now close the environment handle; the flag HAM_AUTO_CLEANUP will
00234    * automatically close all databases and cursors
00235    */
00236   st = ham_env_close(env, HAM_AUTO_CLEANUP);
00237   if (st != HAM_SUCCESS)
00238     error("ham_env_close", st);
00239 
00240   printf("success!\n");
00241   return (0);
00242 }
00243