hamsterdb Embedded Database 1.1.13
|
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