00001 #include <sys/types.h>
00002
00003 #include <errno.h>
00004 #include <stdlib.h>
00005 #include <string.h>
00006 #include <unistd.h>
00007 #include <stdio.h>
00008
00009 #include <db.h>
00010
00011 #define RPMDB_HOME "/tmp/rpm"
00012 #define RPMDB_Packages "Packages"
00013 #define RPMDB_Dirnames "Dirnames"
00014 #define RPMDB_Basenames "Basenames"
00015
00016 static int nentries = 100;
00017
00018 static int
00019 rnum(int rmin, int rmax)
00020 {
00021 static int initialized = 0;
00022
00023 if (!initialized) {
00024 srand((unsigned)getpid());
00025 initialized = 1;
00026 }
00027
00028 return (rmin + (rand() % rmax));
00029 }
00030
00031 static int
00032 db_init(const char * home, DB_ENV ** dbenvp)
00033 {
00034 DB_ENV * dbenv;
00035 u_int32_t flags;
00036 int ret;
00037
00038 if ((ret = db_env_create(&dbenv, 0)) != 0)
00039 goto exit;
00040 dbenv->set_errfile(dbenv, stderr);
00041 dbenv->set_errpfx(dbenv, "tjfn");
00042
00043 flags = DB_CREATE | DB_INIT_MPOOL;
00044 if ((ret = dbenv->open(dbenv, home, flags, 0)) != 0)
00045 goto exit;
00046
00047 exit:
00048 if (dbenvp != NULL && ret == 0)
00049 *dbenvp = dbenv;
00050 else if (dbenv)
00051 (void) dbenv->close(dbenv, 0);
00052
00053 return ret;
00054 }
00055
00056 static int
00057 db_open(const char * dbfn, DB_ENV * dbenv, DB ** dbp)
00058 {
00059 DB * db = NULL;
00060 int ret;
00061
00062 if ((ret = db_create(&db, dbenv, 0)) != 0) {
00063 fprintf(stderr, "db_create: %s\n", db_strerror(ret));
00064 goto err;
00065 }
00066
00067 if ((ret = db->set_flags(db, DB_DUP)) != 0) {
00068 db->err(db, ret, "db->set_flags(%s)", dbfn);
00069 goto err;
00070 }
00071
00072 #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 1)
00073 ret = db->open(db, NULL, dbfn, NULL, DB_BTREE, DB_CREATE, 0664);
00074 #else
00075 ret = db->open(db, dbfn, NULL, DB_BTREE, DB_CREATE, 0664);
00076 #endif
00077 if (ret != 0) {
00078 db->err(db, ret, "db->open(%s)", dbfn);
00079 goto err;
00080 }
00081
00082 err:
00083 if (dbp != NULL && ret == 0)
00084 *dbp = db;
00085 else if (db)
00086 (void) db->close(db, 0);
00087 return ret;
00088 }
00089
00090 static int
00091 db_put(DB * db, const char * kstr, int klen, const char * dstr, int dlen)
00092 {
00093 DBT key, data;
00094 int ret;
00095
00096 memset(&key, 0, sizeof(key));
00097 memset(&data, 0, sizeof(data));
00098
00099 if (klen <= 0)
00100 klen = strlen(kstr) + 1;
00101 if (dlen <= 0)
00102 dlen = strlen(dstr) + 1;
00103 key.data = (void *)kstr;
00104 key.size = klen;
00105 data.data = (void *)dstr;
00106 data.size = dlen;
00107
00108 ret = db->put(db, NULL, &key, &data, 0);
00109 if (ret == DB_KEYEXIST)
00110 ret = 0;
00111
00112 return ret;
00113 }
00114
00115 static int
00116 db_join(DB * pkgdb, DB * dndb, DB * bndb)
00117 {
00118 char kstr[256], dstr[256];
00119 DBC *dndbc = NULL;
00120 DBC *bndbc = NULL;
00121 DBC *dbc = NULL;
00122 DBC *carray[3];
00123 DBT bnkey, bndata;
00124 DBT dnkey, dndata;
00125 DBT key, data;
00126 int ret, tret;
00127 int i, j, k;
00128
00129 if ((ret = dndb->cursor(dndb, NULL, &dndbc, 0)) != 0)
00130 goto err;
00131
00132 i = rnum(0, nentries);
00133 j = i;
00134 k = i;
00135
00136 sprintf(kstr, "DN%d", i);
00137 sprintf(dstr, "%04d", k);
00138 memset(&dnkey, 0, sizeof(dnkey));
00139 memset(&dndata, 0, sizeof(dndata));
00140 dnkey.data = kstr;
00141 dnkey.size = strlen(kstr) + 1;
00142 dnkey.ulen = 0;
00143 dnkey.dlen = 0;
00144 dnkey.doff = 0;
00145 dnkey.flags = 0;
00146 if ((ret = dndbc->c_get(dndbc, &dnkey, &dndata, DB_SET_RANGE)) != 0)
00147 goto err;
00148
00149 if ((ret = bndb->cursor(bndb, NULL, &bndbc, 0)) != 0)
00150 goto err;
00151 sprintf(kstr, "BN%d", i);
00152 sprintf(dstr, "%04d", i);
00153 memset(&bnkey, 0, sizeof(bnkey));
00154 memset(&bndata, 0, sizeof(bndata));
00155 bnkey.data = kstr;
00156 bnkey.size = strlen(kstr) + 1;
00157 bnkey.ulen = 0;
00158 bnkey.dlen = 0;
00159 bnkey.doff = 0;
00160 bnkey.flags = 0;
00161 if ((ret = bndbc->c_get(bndbc, &bnkey, &bndata, DB_SET_RANGE)) != 0)
00162 goto err;
00163
00164 carray[0] = dndbc;
00165 carray[1] = bndbc;
00166 carray[2] = NULL;
00167
00168 if ((ret = pkgdb->join(pkgdb, carray, &dbc, 0)) != 0)
00169 goto err;
00170 memset(&key, 0, sizeof(key));
00171 memset(&data, 0, sizeof(data));
00172 while ((ret = dbc->c_get(dbc, &key, &data, DB_JOIN_ITEM)) == 0) {
00173
00174 fprintf(stderr, "*** Get db %p key (%s,%d) data (%s,%d)\n", pkgdb, (char *)key.data, key.size, (char *)data.data, data.size);
00175 }
00176
00177
00178
00179
00180
00181 if (ret == DB_NOTFOUND)
00182 ret = 0;
00183
00184 err:
00185 if (dbc != NULL && (tret = dbc->c_close(dbc)) != 0 && ret == 0)
00186 ret = tret;
00187 if (dndbc != NULL && (tret = dndbc->c_close(dndbc)) != 0 && ret == 0)
00188 ret = tret;
00189 if (bndbc != NULL && (tret = bndbc->c_close(bndbc)) != 0 && ret == 0)
00190 ret = tret;
00191
00192 return (ret);
00193 }
00194
00195 int
00196 main(int argc, char *argv[])
00197 {
00198 char kstr[256], dstr[256];
00199 DB_ENV * dbenv = NULL;
00200 DB * pkgdb = NULL;
00201 DB * dndb = NULL;
00202 DB * bndb = NULL;
00203 int ret, t_ret;
00204 int i;
00205
00206 (void) mkdir(RPMDB_HOME, 0755);
00207
00208 if ((ret = db_init(RPMDB_HOME, &dbenv)) != 0) {
00209 fprintf(stderr, "db_init(%s): %s\n", RPMDB_HOME, db_strerror(ret));
00210 goto err;
00211 }
00212
00213 if ((ret = db_open(RPMDB_Packages, dbenv, &pkgdb)) != 0) {
00214 fprintf(stderr, "db_open(%s): %s\n", RPMDB_Packages, db_strerror(ret));
00215 goto err;
00216 }
00217 for (i = 0; i < nentries; i++) {
00218 sprintf(kstr, "%08d", i);
00219 sprintf(dstr, "PKG%d", i);
00220 if ((ret = db_put(pkgdb, kstr, 0, dstr, 0)) != 0) {
00221 fprintf(stderr, "db_put(%s): %s\n", RPMDB_Packages, db_strerror(ret));
00222 goto err;
00223 }
00224 }
00225
00226 if ((ret = db_open(RPMDB_Dirnames, dbenv, &dndb)) != 0) {
00227 fprintf(stderr, "db_open(%s): %s\n", RPMDB_Dirnames, db_strerror(ret));
00228 goto err;
00229 }
00230 for (i = 0; i < nentries; i++) {
00231 sprintf(kstr, "DN%d", i);
00232 sprintf(dstr, "%08d", i);
00233 if ((ret = db_put(dndb, kstr, 0, dstr, 0)) != 0) {
00234 fprintf(stderr, "db_put(%s): %s\n", RPMDB_Dirnames, db_strerror(ret));
00235 goto err;
00236 }
00237 }
00238
00239 if ((ret = db_open(RPMDB_Basenames, dbenv, &bndb)) != 0) {
00240 fprintf(stderr, "db_open(%s): %s\n", RPMDB_Basenames, db_strerror(ret));
00241 goto err;
00242 }
00243 for (i = 0; i < nentries; i++) {
00244 sprintf(kstr, "BN%d", i);
00245 sprintf(dstr, "%08d", i);
00246 if ((ret = db_put(bndb, kstr, 0, dstr, 0)) != 0) {
00247 fprintf(stderr, "db_put(%s): %s\n", RPMDB_Basenames, db_strerror(ret));
00248 goto err;
00249 }
00250 }
00251
00252 if ((ret = db_join(pkgdb, dndb, bndb)) != 0) {
00253 fprintf(stderr, "db_join: %s\n", db_strerror(ret));
00254 goto err;
00255 }
00256
00257 err:
00258 if (dbenv != NULL) {
00259 if (pkgdb != NULL) {
00260 if ((t_ret = pkgdb->close(pkgdb, 0)) != 0 && ret == 0)
00261 ret = t_ret;
00262 }
00263 if (dndb != NULL) {
00264 if ((t_ret = dndb->close(dndb, 0)) != 0 && ret == 0)
00265 ret = t_ret;
00266 }
00267 if (bndb != NULL) {
00268 if ((t_ret = bndb->close(bndb, 0)) != 0 && ret == 0)
00269 ret = t_ret;
00270 }
00271 (void) dbenv->close(dbenv, 0);
00272 }
00273
00274 return 0;
00275 }