00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <db/db.h>
00004 #include <string.h>
00005 #include <glib.h>
00006
00007 #include <sys/types.h>
00008 #include <sys/stat.h>
00009 #include <sys/time.h>
00010 #include <fcntl.h>
00011 #include <unistd.h>
00012
00013
00014
00015 typedef unsigned int uint;
00016
00017 static int bm_compare_key_trans(const DBT *a, const DBT *b) {
00018 uint* tmpa = (uint*)(a->data);
00019 uint* tmpb = (uint*)(b->data);
00020
00021 if((*tmpa) == (*tmpb)) return 0;
00022 if(*tmpa > *tmpb) return 1;
00023 else return -1;
00024 }
00025
00026 static int bm_compare_key_words(const DBT *a, const DBT *b) {
00027 char* tmpa = g_utf8_casefold((char*)(a->data),-1);
00028 char* tmpb = g_utf8_casefold((char*)(b->data),-1);
00029 int result = g_utf8_collate(tmpa,tmpb);
00030 g_free(tmpa);
00031 g_free(tmpb);
00032 return result;
00033 }
00034
00035
00036 int read_berkeley_in_string_mode(DB* dbp) {
00037 DBT key = { NULL , 0 };
00038 DBT val = { NULL , 0 };
00039
00040 int result = dbp->seq(dbp, &key, &val, R_FIRST);
00041 uint count = 1;
00042 uint a = 0;
00043 uint b = 0;
00044 uint c = 0;
00045 uint i = 0;
00046 uint* t = NULL;
00047 while(1 != result) {
00048 if(-1 == result) {
00049 printf("---Error! While sequentiall reading database\n");
00050 return 10;
00051 };
00052 memcpy(&a, val.data, sizeof(uint));
00053 t = (uint*)(val.data + sizeof(uint));
00054 printf("%4d. word = %-30s [%-2d record(s)] => \n",count, (char*)(key.data), a);
00055
00056 for(i=0; i < a; ++i) {
00057 b = t[i*2];
00058 c = t[i*2 + 1];
00059 printf("\t%4u.%u. ID = %u [hash = %#x]\n",count,i+1,b,c);
00060 }
00061
00062 result = dbp->seq(dbp, &key, &val, R_NEXT);
00063 ++count;
00064 }
00065 return 0;
00066 }
00067
00068 int read_berkeley_in_binary_mode(DB* dbp) {
00069 DBT key = { NULL , 0 };
00070 DBT val = { NULL , 0 };
00071
00072 uint count = 1;
00073 uint a = 0;
00074 char* s = NULL;
00075 int result = dbp->seq(dbp, &key, &val, R_FIRST);
00076 while(1 != result) {
00077 if(-1 == result) {
00078 printf("---Error! While sequentiall reading database\n");
00079 return 10;
00080 };
00081 memcpy(&a, key.data, sizeof(uint));
00082 s = (char*) (val.data);
00083 if(a == 0) {
00084 uint b = 0;
00085 memcpy(&b , val.data, sizeof(uint));
00086 printf("%4u. ID = %-4u value(freeID)=%u\n",count,a,b);
00087 }
00088 else {
00089 printf("%4u. ID = %-4u string=\'%s\'\n",count,a,s);
00090 }
00091
00092 result = dbp->seq(dbp, &key, &val, R_NEXT);
00093 ++count;
00094 }
00095 return 0;
00096 }
00097
00098 int berkeley_del_record(DB* dbp,char mode,char* id) {
00099 uint a;
00100 DBT key = { NULL , 0 };
00101 if('s' == mode) {
00102 printf("Delete key: %s...",id);
00103 key.data = id;
00104 key.size = strlen(id) + 1;
00105 }
00106 else if('b' == mode) {
00107 if(1 != sscanf(id,"%u",&a)) {
00108 printf("ID has wrong format - it should be unsigned int!\n");
00109 return 25;
00110 };
00111 printf("Deleting record with id=%u\n",a);
00112 key.size = sizeof(uint);
00113 key.data = &a;
00114 }
00115 else {
00116 printf("not supported mode for delete action!\n");
00117 return 24;
00118 };
00119
00120 int result = dbp->del(dbp,&key,0);
00121 if(1 == result) {
00122 printf("... there was no such an element!\n");
00123 }
00124 else if(-1 == result) {
00125 printf("---Error while deleteing record!\n");
00126 return 29;
00127 }
00128 else {
00129 printf("... record deleted!\n");
00130 }
00131
00132 return 0;
00133 }
00134
00135 int berkeley_fnd_record(DB* dbp,char mode,char* id) {
00136 uint a = 0;
00137 DBT key = { NULL , 0 };
00138 DBT val = { NULL , 0 };
00139 if('s' == mode) {
00140 printf("Searching for key: %s...\n",id);
00141 key.data = id;
00142 key.size = strlen(id) + 1;
00143 }
00144 else if('b'== mode) {
00145 if(1 != sscanf(id,"%u",&a)) {
00146 printf("ID has wrong format - it should be unsigned int!\n");
00147 return 35;
00148 };
00149 printf("Searching for record with id=%u\n",a);
00150 key.size = sizeof(uint);
00151 key.data = &a;
00152 }
00153 else {
00154 printf("not supported mode for find action!\n");
00155 return 30;
00156 };
00157
00158 int result = dbp->get(dbp,&key,&val,0);
00159 if(1 == result) {
00160 printf("... there was no such a record\n");
00161 }
00162 else if(-1 == result) {
00163 printf("---Error while searching for the record!\n");
00164 return 29;
00165 }
00166 else {
00167 uint* t = NULL;
00168 uint b = 0, c = 0, i = 0;
00169 char* s = NULL;
00170 switch(mode) {
00171 case 's':
00172
00173 memcpy(&a, val.data, sizeof(uint));
00174 t = (uint*)(val.data + sizeof(uint));
00175 printf("Element word = %-30s [%-2d record(s)] => \n", (char*)(key.data), a);
00176
00177 for(i=0; i < a; ++i) {
00178 b = t[i*2];
00179 c = t[i*2 + 1];
00180 printf("\t%2u. ID = %u [hash = %#xu]\n",i+1,b,c);
00181 }
00182 break;
00183
00184 case 'b':
00185
00186 s = (char*) (val.data);
00187 if(a == 0) {
00188 memcpy(&b , val.data, sizeof(uint));
00189 printf("Element ID = %-4u value(freeID)=%u\n",a,b);
00190 }
00191 else {
00192 printf("Element ID = %-4u string=\'%s\'\n",a,s);
00193 }
00194 break;
00195
00196 default:
00197 printf("Not supported mode!\n");
00198 return 30;
00199 }
00200 }
00201 return 0;
00202 }
00203
00204 int berkeley_fnd_pattern_record(DB* dbp,char mode,char* id) {
00205 DBT key = { NULL , 0 };
00206 DBT val = { NULL , 0 };
00207
00208 if('s' == mode) {
00209 int result = dbp->seq(dbp, &key, &val, R_FIRST);
00210 uint count = 1;
00211 uint a = 0;
00212 uint b = 0;
00213 uint c = 0;
00214 uint i = 0;
00215 uint* t = NULL;
00216 char* tmp = g_utf8_casefold(id,-1);
00217 uint len = strlen(tmp);
00218 printf("dlugosc: %u\n",len);
00219 char* tmp2 = NULL;
00220 while(1 != result) {
00221 if(-1 == result) {
00222 printf("---Error! While sequentiall reading database\n");
00223 return 10;
00224 };
00225 tmp2 = g_utf8_casefold((char*)(key.data),len);
00226 if(0 == g_utf8_collate(tmp2,tmp) || len == 0) {
00227 memcpy(&a, val.data, sizeof(uint));
00228 t = (uint*)(val.data + sizeof(uint));
00229 printf("%4d. word = %-30s [%-2d record(s)] => \n",count, (char*)(key.data), a);
00230
00231 for(i=0; i < a; ++i) {
00232 b = t[i*2];
00233 c = t[i*2 + 1];
00234 printf("\t%4u.%u. ID = %u [hash = %#xu]\n",count,i+1,b,c);
00235 }
00236 }
00237 result = dbp->seq(dbp, &key, &val, R_NEXT);
00238 ++count;
00239 }
00240 free(tmp);
00241 return 0;
00242 }
00243 else {
00244 printf("Searching for pattern is not supported in binary mode!");
00245 return 65;
00246 }
00247 }
00248
00249 int berkeley_del_pattern_record(DB* dbp,char mode,char *id) {
00250 DBT key = { NULL , 0 };
00251 DBT val = { NULL , 0 };
00252
00253 if('s' == mode) {
00254 int result = dbp->seq(dbp, &key, &val, R_FIRST);
00255 uint count = 0;
00256 uint a = 0;
00257 uint b = 0;
00258 uint c = 0;
00259 uint i = 0;
00260 uint* t = NULL;
00261 char* tmp = g_utf8_casefold(id,-1);
00262 uint len = strlen(tmp);
00263 char* tmp2 = NULL;
00264 while(1 != result) {
00265 if(-1 == result) {
00266 printf("---Error! While sequentiall reading database\n");
00267 return 10;
00268 };
00269 tmp2 = g_utf8_casefold((char*)(key.data),len);
00270 if(0 == g_utf8_collate(tmp2,tmp) || len == 0) {
00271
00272
00273 memcpy(&a, val.data, sizeof(uint));
00274 t = (uint*)(val.data + sizeof(uint));
00275 printf("Deleting record %4d. word = %-30s [%-2d record(s)] => \n",count, (char*)(key.data), a);
00276
00277 for(i=0; i < a; ++i) {
00278 b = t[i*2];
00279 c = t[i*2 + 1];
00280 printf("\t%4u.%u. ID = %u [hash = %#xu]\n",count,i+1,b,c);
00281 }
00282 int result = dbp->del(dbp,&key,0);
00283 if(1 == result) {
00284 printf("---Error find element but could not delete it!\n");
00285 }
00286 else if(-1 == result) {
00287 printf("---Error while deleteing record!\n");
00288 return 29;
00289 }
00290 else {
00291 printf("... record deleted!\n");
00292 }
00293 count++;
00294 }
00295 free(tmp2); tmp2 = NULL;
00296 result = dbp->seq(dbp, &key, &val, R_NEXT);
00297 }
00298 printf("%u record were deleted totaly.\n",count);
00299 free(tmp);
00300 return 0;
00301 }
00302 else {
00303 printf("Searching for pattern is not supported in binary mode!");
00304 return 65;
00305 }
00306 }
00307
00308 int berkeley_add_record(DB* dbp,char mode,char* id, char* value) {
00309 DBT key = { NULL , 0 };
00310 DBT val = { NULL , 0 };
00311
00312 int result = 0;
00313 uint a = 0, i = 0, error = 0, b = 0, c = 0;
00314 uint* t = NULL;
00315 char* tmp = malloc(200);
00316 char* tmp_original = tmp;
00317 if('s' == mode) {
00318 printf("Adding record with key = %s...\n",id);
00319 key.data = id;
00320 key.size = strlen(id) + 1;
00321 while(1) {
00322 if(2 != sscanf(value,"%u%[ 0-9]",&a,tmp)) {
00323 result = 43;
00324 break;
00325 }
00326 val.size = sizeof(uint) * (a*2 + 1);
00327 t = (uint*)malloc( val.size );
00328 t[0] = a;
00329 for(i=0; i< a; ++i) {
00330 if(2 != sscanf(tmp,"%u%[ 0-9]",&b,tmp)) {
00331 error = 1;
00332 break;
00333 };
00334 t[1+i*2] = b;
00335 int n = sscanf(tmp,"%u%[ 0-9]",&b,tmp);
00336 if(( (2 != n) && (i!=(a-1)) ) || ((1!=n) && (i==(a-1)))) {
00337 error = 1;
00338 break;
00339 };
00340 t[1+i*2+1] = b;
00341 }
00342 if(error) {
00343 printf("Wrong value for string database!\n");
00344 result = 44;
00345 break;
00346 }
00347 val.data = t;
00348 break ;}
00349 }
00350 else if('b'== mode) {
00351 if(1 != sscanf(id,"%u",&a)) {
00352 printf("ID has wrong format - it should be unsigned int!\n");
00353 return 45;
00354 };
00355 printf("Adding record with id=%u\n",a);
00356 key.size = sizeof(uint);
00357 key.data = &a;
00358 if(0 == a) {
00359 if(1 != sscanf(value,"%u",&c)) {
00360 printf("Value has wrong format for record with ID=0 (freeID - unsinged int)\n");
00361 return 46;
00362 };
00363 val.size = key.size;
00364 val.data = &c;
00365 }
00366 else {
00367 val.size = strlen(value) + 1;
00368 val.data = value;
00369 }
00370 }
00371 else {
00372 printf("---Not supported mode for add action!\n");
00373 return 40;
00374 };
00375
00376 if(0 != result) {
00377 if(t) free(t);
00378 free(tmp_original);
00379 return result;
00380 }
00381
00382 result = dbp->put(dbp, &key, &val, R_NOOVERWRITE);
00383 if(1 == result) {
00384 printf("Such a key already exist in database!\n");
00385 result = 41;
00386 }
00387 else if(-1 == result) {
00388 printf("---Error while adding new record!\n");
00389 result = 49;
00390 }
00391 else {
00392 printf("New record has been added.\n");
00393 if(-1 == dbp->sync(dbp, 0)) {
00394 printf("---Error while saving data to file! Record could be lost.\n");
00395 result = 48;
00396 }
00397 }
00398 if(t) free(t);
00399 return result;
00400 }
00401
00402 int main(int argc, char* argv[]) {
00403 int help = 0, i = 0;
00404 for(i=1;i<argc;++i) {
00405 if((0 == strcmp("help",argv[i])) ||
00406 (0 == strcmp("--help",argv[i])) ||
00407 (0 == strcmp("-help",argv[i])) ||
00408 (0 == strcmp("-h",argv[i])) ||
00409 (0 == strcmp("/h",argv[i])) ||
00410 (0 == strcmp("/help",argv[i]))) {
00411 help = 1;
00412 break;
00413 }
00414 }
00415 if((argc < 3) || help) {
00416 printf("[Usage: bdbprint s|b file_name.db (action identifier_of_record (optional_value))]\n"
00417 "\tfile_name.db - database to open and print\n"
00418 "\t s - open in string mode, every key is treated as a string\n"
00419 "\t b - open in binary mode, every key is treated as a unsigned integer\n"
00420 "\t action - optional action to do on the base\n"
00421 "\t\t del - delete record with key=identifier_of_record\n"
00422 "\t\t add - add new record with key=identifier_of_record\n"
00423 "\t\t fnd - find record with key=identifier_of_record\n"
00424 "\t\t\t optional_value - value for add action\n");
00425 return 100;
00426 };
00427
00428 char* filename = argv[2];
00429 char* _mode = argv[1];
00430 if((strlen(_mode) > 1) || ( ('s' != _mode[0]) && ('b' != _mode[0]) )) {
00431 printf("Wrong mode! Mode could be only s or b [\'s\' , \'b\']!\n");
00432 return 2;
00433 }
00434 char mode = _mode[0];
00435
00436 BTREEINFO info = {
00437 0,
00438 0,
00439 0,
00440 0,
00441 0,
00442 bm_compare_key_words,
00443 NULL
00444 };
00445 if('b' == mode) {
00446 info.compare = bm_compare_key_trans;
00447 }
00448 u_int32_t flags = O_CREAT | O_RDWR;
00449 DB *dbp = dbopen(filename, flags, 0755, DB_BTREE, &info);
00450 if(NULL == dbp) {
00451 printf("Could not open database: %s!\n",filename);
00452 return 1;
00453 };
00454
00455 int result = 0;
00456 if(argc == 3) {
00457 printf("Printing database: \'%s\' in mode %s :\n", filename, _mode);
00458 if('s' == mode) {
00459 result = read_berkeley_in_string_mode(dbp);
00460 }
00461 else if('b' == mode) {
00462 result = read_berkeley_in_binary_mode(dbp);
00463 }
00464 }
00465 else if(argc > 3) {
00466 printf("Do not print - only action... [mode=%s]\n",_mode);
00467 if(argc < 5) {
00468 printf("Wrong number of parameters! probably You did not give id of record for action.\n");
00469 return 21;
00470 };
00471 char* action = argv[3];
00472 if(strcmp(action,"del") == 0) {
00473 if('*' == argv[4][0]) {
00474 result = berkeley_del_pattern_record(dbp,mode,&(argv[4][1]));
00475 }
00476 else {
00477 result = berkeley_del_record(dbp,mode,argv[4]);
00478 }
00479 }
00480 else if(strcmp(action,"fnd") == 0) {
00481 if('*' == argv[4][0]) {
00482 result = berkeley_fnd_pattern_record(dbp,mode,argv[4]+1);
00483 }
00484 else {
00485 result = berkeley_fnd_record(dbp,mode,argv[4]);
00486 }
00487 }
00488 else if(strcmp(action,"add") == 0) {
00489 if(argc < 6) {
00490 printf("You did not give value for new record!\n");
00491 return 22;
00492 };
00493 result = berkeley_add_record(dbp,mode,argv[4],argv[5]);
00494 }
00495 else {
00496 printf("Not supported action: %s! The only good values are: add, del, fnd.\n",action);
00497 result = 20;
00498 }
00499 }
00500
00501 dbp->close(dbp);
00502 return result;
00503 }
00504