hamsterdb Embedded Database 1.1.13

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 #if UNDER_CE
00020 #   include <windows.h>
00021 #endif
00022 #include <ham/hamsterdb.h>
00023 
00024 void 
00025 error(const char *foo, ham_status_t st)
00026 {
00027 #if UNDER_CE
00028     wchar_t title[1024];
00029     wchar_t text[1024];
00030 
00031     MultiByteToWideChar(CP_ACP, 0, foo, -1, title, 
00032             sizeof(title)/sizeof(wchar_t));
00033     MultiByteToWideChar(CP_ACP, 0, ham_strerror(st), -1, text, 
00034             sizeof(text)/sizeof(wchar_t));
00035 
00036     MessageBox(0, title, text, 0);
00037 #endif
00038     printf("%s() returned error %d: %s\n", foo, st, ham_strerror(st));
00039     exit(-1);
00040 }
00041 
00042 #define MAX_DBS             2
00043 
00044 #define DBNAME_CUSTOMER     1
00045 #define DBNAME_ORDER        2
00046 
00047 #define MAX_CUSTOMERS       4
00048 #define MAX_ORDERS          8
00049 
00050 /* 
00051  * a structure for the "customer" database
00052  */
00053 typedef struct
00054 {
00055     int id;                 /* customer id */
00056     char name[32];          /* customer name */
00057     /* ... additional information could follow here */
00058 } customer_t;
00059 
00060 /* 
00061  * a structure for the "orders" database
00062  */
00063 typedef struct
00064 {
00065     int id;                 /* order id */
00066     int customer_id;        /* customer id */
00067     char assignee[32];      /* assigned to whom? */
00068     /* ... additional information could follow here */
00069 } order_t;
00070 
00071 int 
00072 main(int argc, char **argv)
00073 {
00074     int i;
00075     ham_status_t st;        /* status variable */
00076     ham_db_t *db[MAX_DBS];  /* hamsterdb database objects */
00077     ham_env_t *env;         /* hamsterdb environment */
00078     ham_cursor_t *cursor[MAX_DBS]; /* a cursor for each database */
00079     ham_key_t key, cust_key, ord_key;
00080     ham_record_t record, cust_record, ord_record;
00081 
00082     customer_t customers[MAX_CUSTOMERS]={
00083         { 1, "Alan Antonov Corp." },
00084         { 2, "Barry Broke Inc." },
00085         { 3, "Carl Caesar Lat." },
00086         { 4, "Doris Dove Brd." }
00087     };
00088 
00089     order_t orders[MAX_ORDERS]={
00090         { 1, 1, "Joe" },
00091         { 2, 1, "Tom" },
00092         { 3, 3, "Joe" },
00093         { 4, 4, "Tom" },
00094         { 5, 3, "Ben" },
00095         { 6, 3, "Ben" },
00096         { 7, 4, "Chris" },
00097         { 8, 1, "Ben" }
00098     };
00099 
00100     memset(&key, 0, sizeof(key));
00101     memset(&record, 0, sizeof(record));
00102     memset(&cust_key, 0, sizeof(cust_key));
00103     memset(&cust_record, 0, sizeof(cust_record));
00104     memset(&ord_key, 0, sizeof(ord_key));
00105     memset(&ord_record, 0, sizeof(ord_record));
00106 
00107     /*
00108      * first, create a new hamsterdb environment 
00109      */
00110     st=ham_env_new(&env);
00111     if (st!=HAM_SUCCESS)
00112         error("ham_env_new", st);
00113 
00114     /*
00115      * then create the database objects
00116      */
00117     for (i=0; i<MAX_DBS; i++) {
00118         st=ham_new(&db[i]);
00119         if (st!=HAM_SUCCESS)
00120             error("ham_new", st);
00121     }
00122 
00123     /*
00124      * now create a new database file for the environment
00125      *
00126      * we could also use ham_env_create_ex() if we wanted to specify the 
00127      * page size, key size or cache size limits
00128      */
00129     st=ham_env_create(env, "test.db", 0, 0664);
00130     if (st!=HAM_SUCCESS)
00131         error("ham_env_create", st);
00132 
00133     /*
00134      * then create the two databases in this environment; each database
00135      * has a name - the first is our "customer" database, the second 
00136      * is for the "orders"
00137      */
00138     st=ham_env_create_db(env, db[0], DBNAME_CUSTOMER, 0, 0);
00139     if (st!=HAM_SUCCESS)
00140         error("ham_env_create_db (customer)", st);
00141     st=ham_env_create_db(env, db[1], DBNAME_ORDER, 0, 0);
00142     if (st!=HAM_SUCCESS)
00143         error("ham_env_create_db (order)", st);
00144 
00145     /* 
00146      * create a cursor for each database
00147      */
00148     for (i=0; i<MAX_DBS; i++) {
00149         st=ham_cursor_create(db[i], 0, 0, &cursor[i]);
00150         if (st!=HAM_SUCCESS) {
00151             printf("ham_cursor_create() failed with error %d\n", st);
00152             return (-1);
00153         }
00154     }
00155 
00156     /*
00157      * insert a few customers in the first database
00158      */
00159     for (i=0; i<MAX_CUSTOMERS; i++) {
00160         key.size=sizeof(int);
00161         key.data=&customers[i].id;
00162 
00163         record.size=sizeof(customer_t);
00164         record.data=&customers[i];
00165 
00166         /* note: the second parameter of ham_insert() is reserved; set it to 
00167          * NULL */
00168         st=ham_insert(db[0], 0, &key, &record, 0);
00169         if (st!=HAM_SUCCESS)
00170             error("ham_insert (customer)", st);
00171     }
00172 
00173     /*
00174      * and now the orders in the second database
00175      */
00176     for (i=0; i<MAX_ORDERS; i++) {
00177         key.size=sizeof(int);
00178         key.data=&orders[i].id;
00179 
00180         record.size=sizeof(order_t);
00181         record.data=&orders[i];
00182 
00183         /* note: the second parameter of ham_insert() is reserved; set it to 
00184          * NULL */
00185         st=ham_insert(db[1], 0, &key, &record, 0);
00186         if (st!=HAM_SUCCESS)
00187             error("ham_insert (order)", st);
00188     }
00189 
00190     /*
00191      * to demonstrate even more functions, close all objects, then
00192      * re-open the environment and the two databases.
00193      *
00194      * note that ham_env_close automatically calls ham_close on all 
00195      * databases.
00196      */
00197     for (i=0; i<MAX_DBS; i++) {
00198         st=ham_cursor_close(cursor[i]);
00199         if (st!=HAM_SUCCESS)
00200             error("ham_cursor_close", st);
00201     }
00202     st=ham_env_close(env, 0);
00203     if (st!=HAM_SUCCESS)
00204         error("ham_env_close", st);
00205 
00206     /*
00207      * now reopen the environment and the databases 
00208      */
00209     st=ham_env_open(env, "test.db", 0);
00210     if (st!=HAM_SUCCESS)
00211         error("ham_env_open", st);
00212     st=ham_env_open_db(env, db[0], DBNAME_CUSTOMER, 0, 0);
00213     if (st!=HAM_SUCCESS)
00214         error("ham_env_open_db (customer)", st);
00215     st=ham_env_open_db(env, db[1], DBNAME_ORDER, 0, 0);
00216     if (st!=HAM_SUCCESS)
00217         error("ham_env_open_db (order)", st);
00218 
00219     /* 
00220      * re-create a cursor for each database
00221      */
00222     for (i=0; i<MAX_DBS; i++) {
00223         st=ham_cursor_create(db[i], 0, 0, &cursor[i]);
00224         if (st!=HAM_SUCCESS) {
00225             printf("ham_cursor_create() failed with error %d\n", st);
00226             return (-1);
00227         }
00228     }
00229 
00230     /*
00231      * now start the query - we want to dump each customer with his
00232      * orders
00233      *
00234      * we have a loop with two cursors - the first cursor looping over
00235      * the database with customers, the second loops over the orders
00236      */
00237     while (1) {
00238         customer_t *customer;
00239 
00240         st=ham_cursor_move(cursor[0], &cust_key, &cust_record, HAM_CURSOR_NEXT);
00241         if (st!=HAM_SUCCESS) {
00242             /* reached end of the database? */
00243             if (st==HAM_KEY_NOT_FOUND)
00244                 break;
00245             else
00246                 error("ham_cursor_next(customer)", st);
00247         }
00248 
00249         customer=(customer_t *)cust_record.data;
00250 
00251         /* print the customer id and name */
00252         printf("customer %d ('%s')\n", customer->id, customer->name);
00253 
00254         /*
00255          * the inner loop prints all orders of this customer
00256          *
00257          * before we start the loop, we move the cursor to the
00258          * first entry
00259          */
00260         st=ham_cursor_move(cursor[1], &ord_key, &ord_record, HAM_CURSOR_FIRST);
00261         if (st!=HAM_SUCCESS) {
00262             /* reached end of the database? */
00263             if (st==HAM_KEY_NOT_FOUND)
00264                 continue;
00265             else
00266                 error("ham_cursor_next(order)", st);
00267         }
00268 
00269         do {
00270             order_t *order;
00271 
00272             order=(order_t *)ord_record.data;
00273 
00274             /* print this order, if it belongs to the current customer */
00275             if (order->customer_id==customer->id)
00276                 printf("  order: %d (assigned to %s)\n", 
00277                         order->id, order->assignee);
00278 
00279             st=ham_cursor_move(cursor[1], &ord_key, 
00280                     &ord_record, HAM_CURSOR_NEXT);
00281             if (st!=HAM_SUCCESS) {
00282                 /* reached end of the database? */
00283                 if (st==HAM_KEY_NOT_FOUND)
00284                     break;
00285                 else
00286                     error("ham_cursor_next(order)", st);
00287             }
00288         } while(1);
00289     }
00290 
00291     /*
00292      * now close the environment handle; the flag
00293      * HAM_AUTO_CLEANUP will automatically close all databases and
00294      * cursors
00295      */
00296     st=ham_env_close(env, HAM_AUTO_CLEANUP);
00297     if (st!=HAM_SUCCESS)
00298         error("ham_env_close", st);
00299 
00300     for (i=0; i<MAX_DBS; i++)
00301          ham_delete(db[i]);
00302 
00303     ham_env_delete(env);
00304 
00305 #if UNDER_CE
00306     error("success", 0);
00307 #endif
00308     printf("success!\n");
00309     return (0);
00310 }
00311 
00312 #if UNDER_CE
00313 int 
00314 _tmain(int argc, _TCHAR* argv[])
00315 {
00316     return (main(0, 0));
00317 }
00318 #endif