1m4_ignore([dnl 2#include <sys/types.h> 3#include <sys/stat.h> 4 5#include <errno.h> 6#include <stdarg.h> 7#include <stdlib.h> 8#include <string.h> 9#include <unistd.h> 10 11#include <db.h> 12 13#define MAXIMUM_RETRY 5 14 15int add_color(DB_ENV *, DB *, char *, int); 16 17int add_fruit(DB_ENV *a, DB *b, char *c, char *d) { 18 a = NULL; b = NULL; c = NULL; d = 0; 19 return (0); 20} 21void db_open(DB_ENV *a, DB **b, char *c, int d) { 22 a = NULL; b = NULL; c = NULL; d = 0; 23} 24void usage(){} 25void env_open(DB_ENV **a) { a = NULL; } 26void env_dir_create() {} 27]) 28m4_indent([dnl 29int 30main(int argc, char *argv[]) 31{ 32 extern int optind; 33 DB *db_cats, *db_color, *db_fruit; 34 DB_ENV *dbenv; 35 int ch; 36m4_blank 37 while ((ch = getopt(argc, argv, "")) != EOF) 38 switch (ch) { 39 case '?': 40 default: 41 usage(); 42 } 43 argc -= optind; 44 argv += optind; 45m4_blank 46 env_dir_create(); 47 env_open(&dbenv); 48m4_blank 49 /* Open database: Key is fruit class; Data is specific type. */ 50 db_open(dbenv, &db_fruit, "fruit", 0); 51m4_blank 52 /* Open database: Key is a color; Data is an integer. */ 53 db_open(dbenv, &db_color, "color", 0); 54m4_blank 55 /* 56 * Open database: 57 * Key is a name; Data is: company name, cat breeds. 58 */ 59 db_open(dbenv, &db_cats, "cats", 1); 60m4_blank 61 add_fruit(dbenv, db_fruit, "apple", "yellow delicious"); 62m4_blank 63m4_cbold([dnl 64 add_color(dbenv, db_color, "blue", 0); 65 add_color(dbenv, db_color, "blue", 3);]) 66m4_blank 67 return (0); 68} 69m4_blank 70m4_cbold([dnl 71int 72add_color(DB_ENV *dbenv, DB *dbp, char *color, int increment) 73{ 74 DBT key, data; 75 DB_TXN *tid; 76 int fail, original, ret, t_ret; 77 char buf[64]; 78m4_blank 79 /* Initialization. */ 80 memset(&key, 0, sizeof(key)); 81 key.data = color; 82 key.size = strlen(color); 83 memset(&data, 0, sizeof(data)); 84 data.flags = DB_DBT_MALLOC; 85m4_blank 86 for (fail = 0;;) { 87 /* Begin the transaction. */ 88 if ((ret = dbenv-__GT__txn_begin(dbenv, NULL, &tid, 0)) != 0) { 89 dbenv-__GT__err(dbenv, ret, "DB_ENV-__GT__txn_begin"); 90 exit (1); 91 } 92m4_blank 93 /* 94 * Get the key. If it exists, we increment the value. If it 95 * doesn't exist, we create it. 96 */ 97 switch (ret = dbp-__GT__get(dbp, tid, &key, &data, DB_RMW)) { 98 case 0: 99 original = atoi(data.data); 100 break; 101 case DB_LOCK_DEADLOCK: 102 default: 103 /* Retry the operation. */ 104 if ((t_ret = tid-__GT__abort(tid)) != 0) { 105 dbenv-__GT__err(dbenv, t_ret, "DB_TXN-__GT__abort"); 106 exit (1); 107 } 108 if (fail++ == MAXIMUM_RETRY) 109 return (ret); 110 continue; 111 case DB_NOTFOUND: 112 original = 0; 113 break; 114 } 115 if (data.data != NULL) 116 free(data.data); 117m4_blank 118 /* Create the new data item. */ 119 (void)snprintf(buf, sizeof(buf), "%d", original + increment); 120 data.data = buf; 121 data.size = strlen(buf) + 1; 122m4_blank 123 /* Store the new value. */ 124 switch (ret = dbp-__GT__put(dbp, tid, &key, &data, 0)) { 125 case 0: 126 /* Success: commit the change. */ 127 if ((ret = tid-__GT__commit(tid, 0)) != 0) { 128 dbenv-__GT__err(dbenv, ret, "DB_TXN-__GT__commit"); 129 exit (1); 130 } 131 return (0); 132 case DB_LOCK_DEADLOCK: 133 default: 134 /* Retry the operation. */ 135 if ((t_ret = tid-__GT__abort(tid)) != 0) { 136 dbenv-__GT__err(dbenv, t_ret, "DB_TXN-__GT__abort"); 137 exit (1); 138 } 139 if (fail++ == MAXIMUM_RETRY) 140 return (ret); 141 break; 142 } 143 } 144}])]) 145