GDBMS 1.0
|
00001 #include "maininclude.h" 00002 #include "listi.h" 00003 #include "settings.h" 00004 #include "hash_table.h" 00005 #include "tr_twin_ht.h" 00006 #include "file_semaphore.h" 00007 #include "some_functions.h" 00008 #include "initial_mode_commands.h" 00009 #include "session_mode_commands.h" 00010 #include "transaction_mode_commands.h" 00011 #include "transaction_mode_commands_types.h" 00012 #include "transaction_mode_commands_nodes.h" 00013 #include "transaction_mode_commands_edges.h" 00014 #include "transaction_mode_commands_find.h" 00015 00016 using namespace std; 00017 00018 tr_twin_ht::tr_twin_ht(char* table_name, char* folder_name, int columns_nr, char* columns, char* columns_searchby, char* unique, int tr_id, char* tr_folder, hash_table *rt): hash_table(table_name, tr_folder, columns_nr, columns, columns_searchby, unique) 00019 { 00020 this->trans_id=tr_id; 00021 this->trans_folder=tr_folder; 00022 this->real_table=rt; 00023 } 00024 tr_twin_ht::tr_twin_ht(char* table_name, char* folder_name, char* columns, char* columns_searchby, char* unique, int tr_id, char* tr_folder, hash_table *rt): hash_table(table_name, tr_folder, columns, columns_searchby, unique) 00025 { 00026 this->trans_id=tr_id; 00027 this->trans_folder=tr_folder; 00028 this->real_table=rt; 00029 } 00030 00031 00032 00033 00034 void tr_twin_ht::AddRecord(char* column_names, char* values) 00035 { 00036 00037 int i=this->getMAXID(); 00038 char *maxid_str=strtoint(i); 00039 00040 char *bbuf=0; 00041 bbuf=inttostr(i); 00042 string trf; 00043 trf+=MAINFOLDER; 00044 trf+=this->trans_folder; 00045 trf+="/trans_changed_ids_"; 00046 trf+=this->tblname; 00047 trf+=".xml"; 00048 XMLNode x1, x2, x3; 00049 x1=XMLNode::parseFile(trf.c_str()); 00050 x2=x1.getChildNode("ids"); 00051 x3=x2.addChild("id"); 00052 x3.addText(bbuf); 00053 x3.addAttribute("add", "1"); 00054 x3.addAttribute("myid", bbuf); 00055 x1.writeToFile(trf.c_str()); 00056 hash_table::AddRecord(column_names, values); 00057 if(bbuf) 00058 delete bbuf; 00059 00060 } 00061 00062 void tr_twin_ht::DeleteRecord(char* column_name, char* value) 00063 { 00064 00065 char *bbuf=0; 00066 string trf; 00067 trf+=MAINFOLDER; 00068 trf+=this->trans_folder; 00069 trf+="/trans_changed_ids_"; 00070 trf+=this->tblname; 00071 trf+=".xml"; 00072 bbuf=hash_table::FindRecord(column_name, value, "id"); 00073 if(bbuf){ 00074 XMLNode x, x1, x2; 00075 int i, j; 00076 x=XMLNode::parseFile(trf.c_str()); 00077 x1=x.getChildNode("ids"); 00078 int nnum=x1.nChildNode(); 00079 for(i=0; i<nnum; i++){ 00080 x2=x1.getChildNode("id"); 00081 char *buf1=0; 00082 bool quit=false; 00083 00084 buf1=x2.getText(); 00085 if(!strcmp(buf1, bbuf)){ 00086 x2.deleteNodeContent(); 00087 x.writeToFile(trf.c_str()); 00088 quit=true; 00089 } 00090 00091 if(buf1) 00092 delete buf1; 00093 if(quit) 00094 break; 00095 } 00096 00097 hash_table::DeleteRecord("id", bbuf); 00098 }else{ 00099 char *buf1=0; 00100 buf1=real_table->FindRecord(column_name, value, "id"); 00101 if(buf1){ 00102 //tuk trqbva da se blokira zapisa za drugi potrebiteli i da se vidi dali ne e blokiran ot drugi 00103 this->blockrecord(buf1); 00104 00105 XMLNode x, x1, x2; 00106 x=XMLNode::parseFile(trf.c_str()); 00107 x1=x.getChildNode("ids"); 00108 x2=x1.addChild("id"); 00109 x2.addAttribute("del", "1"); 00110 x2.addText(buf1); 00111 x.writeToFile(trf.c_str()); 00112 00113 00114 } 00115 00116 if(buf1) 00117 delete buf1; 00118 00119 } 00120 00121 00122 00123 00124 00125 if(bbuf) 00126 delete bbuf; 00127 } 00128 char* tr_twin_ht::FindRecord(char* where_column_name, char* where_column_value, char* find_column) 00129 { 00130 char *buf=0; 00131 00132 buf = hash_table::FindRecord(where_column_name, where_column_value, find_column); 00133 if(!buf) 00134 buf = real_table ->FindRecord(where_column_name, where_column_value, find_column); 00135 00136 00137 return buf; 00138 } 00139 void tr_twin_ht::UpdateRecord(char* where_column, char* where_value, char* column_names, char* column_values) 00140 { 00141 string trf; 00142 trf+=MAINFOLDER; 00143 trf+=this->trans_folder; 00144 trf+="/trans_changed_ids_"; 00145 trf+=this->tblname; 00146 trf+=".xml"; 00147 char *buf=0; 00148 buf = hash_table::FindRecord(where_column, where_value, "id"); 00149 if(buf){ 00150 hash_table::UpdateRecord(where_column, where_value, column_names, column_values); 00151 00152 }else{ 00153 buf=real_table->FindRecord(where_column, where_value, "id"); 00154 if(buf){ 00155 //tuk trqbva da se blokira za drugi potrebiteli i da se vidi dali ne e blokirano ot tqh 00156 this->blockrecord(buf); 00157 XMLNode x, x1, x2; 00158 x=XMLNode::parseFile(trf.c_str()); 00159 x1=x.getChildNode("ids"); 00160 x2=x1.addChild("id"); 00161 x2.addAttribute("upd", "1"); 00162 x2.addText(buf); 00163 int myid=this->getMAXID(); 00164 char *myid_str=inttostr(myid); 00165 string cols, vals; 00166 real_table->FindByIdAndReturnColNamesAndValues(buf, cols, vals, myid_str); 00167 x2.addAttribute("myid", myid_str); 00168 //x2.addAttribute("updcols", column_names); 00169 //x2.addAttribute("updvals", column_values); 00170 x.writeToFile(trf.c_str()); 00171 hash_table::AddRecord(cols.c_str(), vals.c_str()); 00172 00173 } 00174 } 00175 00176 00177 00178 if(buf) 00179 delete buf; 00180 } 00181 int tr_twin_ht::begin_transaction() 00182 { 00183 XMLNode x1, x2; 00184 x1=XMLNode::createXMLTopNode("xml"); 00185 x2=x1.addChild("ids"); 00186 string trf; 00187 trf+=MAINFOLDER; 00188 trf+=this->trans_folder; 00189 trf+="/trans_changed_ids_"; 00190 trf+=this->tblname; 00191 00192 trf+=".xml"; 00193 x1.writeToFile(trf.c_str()); 00194 return 0; 00195 } 00196 00197 00198 00199 00200 int tr_twin_ht::end_transaction() 00201 { 00202 string trf; 00203 trf+=MAINFOLDER; 00204 trf+=this->trans_folder; 00205 trf+="/trans_changed_ids_"; 00206 trf+=this->tblname; 00207 trf+=".xml"; 00208 00209 string realfolder; 00210 realfolder+=MAINFOLDER; 00211 realfolder+=this->real_table->table_folder; 00212 00213 XMLNode x, x1, x2; 00214 XMLNode y, y1, y2; 00215 int i, j, ntr=0; 00216 x=XMLNode::parseFile(trf.c_str()); 00217 x1=x.getChildNode("ids"); 00218 //finish updated records 00219 ntr=x1.nChildNode(); 00220 for(i=0; i<ntr; i++){ 00221 x2=x1.getChildNode("id"); 00222 char *buf1=0; 00223 buf1=x2.getAttribute("upd"); 00224 if(buf1){ 00225 if(!strstr(buf1, "1")){ 00226 char *buf2=0; 00227 buf2=x2.getAttribute("myid"); 00228 if(buf2){ 00229 char *buf3=x2.getText(); 00230 if(buf3){ 00231 string cols, vals; 00232 this->FindByIdAndReturnColNamesAndValues(buf2, cols, vals, buf3); 00233 x2.addAttribute("real_id", buf3); 00234 real_table->UpdateRecord("id", buf3, cols.c_str(), vals.c_str()); 00235 delete buf3; 00236 } 00237 00238 00239 } 00240 00241 if(buf2) 00242 delete buf2; 00243 } 00244 00245 } 00246 00247 00248 if(buf1) 00249 delete buf1; 00250 00251 } 00252 x.writeToFile(trf.c_str()); 00253 //x=XMLNode::writeToFile(trf.c_str()); 00254 //finish deleted records 00255 x=XMLNode::parseFile(trf.c_str()); 00256 x1=x.getChildNode("ids"); 00257 ntr=x1.nChildNode(); 00258 for(i=0; i<ntr; i++){ 00259 x2=x1.getChildNode("id"); 00260 char *buf1=0; 00261 char *buf2=0; 00262 buf1=x2.getAttribute("del"); 00263 buf2=x2.getText(); 00264 00265 if(buf1&&buf2){ 00266 real_table->DeleteRecord("id", buf2); 00267 //x2.deleteNodeContent(); 00268 } 00269 00270 if(buf2) 00271 delete buf2; 00272 00273 if(buf1) 00274 delete buf1; 00275 00276 } 00277 //finish added records 00278 x=XMLNode::parseFile(trf.c_str()); 00279 x1=x.getChildNode("ids"); 00280 ntr=x1.nChildNode(); 00281 for(i=0; i<ntr; i++){ 00282 string cls; 00283 string vls; 00284 char *buf1=0; 00285 x2=x1.getChildNode("id"); 00286 buf1=x2.getAttribute("add"); 00287 if(buf1){ 00288 char *buf2=0; 00289 buf2=x2.getText(); 00290 00291 if(buf2){ 00292 int realid=real_table->getMAXID(); 00293 char *buf3=0; 00294 buf3=inttostr(realid); 00295 if(buf3){ 00296 00297 this->FindByIdAndReturnColNamesAndValues(buf2, cls, vls, buf3); 00298 real_table->AddRecord(cls.c_str(), vls.c_str()); 00299 x2.addAttribute("real_id", realid); 00300 } 00301 00302 } 00303 00304 if(buf2) 00305 delete buf2; 00306 00307 } 00308 00309 00310 if(buf1) 00311 delete buf1; 00312 } 00313 x.writeToFile(trf.c_str()); 00314 00315 00316 00317 return 0; 00318 } 00319 void tr_twin_ht::changewithrealconnections(tr_twin_ht* other_tr, char* col1, char* col2) 00320 { 00321 string trf; 00322 trf+=MAINFOLDER; 00323 trf+=this->trans_folder; 00324 trf+="/trans_changed_ids_"; 00325 trf+=this->tblname; 00326 trf+=".xml"; 00327 00328 00329 00330 XMLNode x, x1, x2; 00331 XMLNode y, y1, y2; 00332 int i, j, ntr=0; 00333 x=XMLNode::parseFile(trf.c_str()); 00334 x1=x.getChildNode("ids"); 00335 ntr=x1.nChildNode(); 00336 for(i=0; i<ntr; i++){ 00337 x2=x1.getChildNode("id"); 00338 char *real_idstr=0; 00339 if(real_idstr=x2.getAttribute("real_id")){ 00340 char *col1v=this->real_table->FindRecord("id", real_idstr, col1); 00341 char *col2v=this->real_table->FindRecord("id", real_idstr, col2); 00342 listi lcol1(col1v, ','); 00343 listi lcol2(col2v, ','); 00344 listi lcol1_new(0, ','); 00345 listi lcol2_new(0, ','); 00346 int nlcol1=lcol1.getnum(); 00347 int nlcol2=lcol2.getnum(); 00348 int j; 00349 for(j=0; j<nlcol1; j++){ 00350 if(strtoint(lcol1.getith(j))<0x80000000){ 00351 lcol1_new.addelement(lcol1.getith(j)); 00352 }else{ 00353 lcol1_new.addelement(other_tr->getrealidforfake(lcol1.getith(j))); 00354 } 00355 00356 } 00357 this->real_table->UpdateRecord("id", real_idstr, col1, lcol1_new.returnstring()); 00358 //za 2rata kolona 00359 for(j=0; j<nlcol2; j++){ 00360 if(strtoint(lcol2.getith(j))<0x80000000){ 00361 lcol2_new.addelement(lcol2.getith(j)); 00362 }else{ 00363 lcol2_new.addelement(other_tr->getrealidforfake(lcol2.getith(j))); 00364 } 00365 00366 } 00367 this->real_table->UpdateRecord("id", real_idstr, col2, lcol2_new.returnstring()); 00368 00369 00370 00371 delete real_idstr; 00372 } 00373 00374 } 00375 00376 /* 00377 //delete the folder of the transaction 00378 string cmd; 00379 cmd+="rm -r "; 00380 cmd+=MAINFOLDER; 00381 cmd+=this->trans_folder; 00382 system(cmd); 00383 */ 00384 } 00385 char* tr_twin_ht::getrealidforfake(char* fakeid) 00386 { 00387 string trf; 00388 trf+=MAINFOLDER; 00389 trf+=this->trans_folder; 00390 trf+="/trans_changed_ids_"; 00391 trf+=this->tblname; 00392 trf+=".xml"; 00393 00394 char *retvalue=0; 00395 00396 XMLNode x, x1, x2; 00397 XMLNode y, y1, y2; 00398 int i, j, ntr=0; 00399 x=XMLNode::parseFile(trf.c_str()); 00400 x1=x.getChildNode("ids"); 00401 ntr=x1.nChildNode(); 00402 int foundindex; 00403 for(i=0; i<ntr; i++){ 00404 x2=x1.getChildNode("id", &foundindex); 00405 char *attrbuf=x2.getAttribute("myid"); 00406 if(attrbuf){ 00407 if(!strcmp(fakeid, attrbuf)){ 00408 x2=x1.getChildNode(foundindex); 00409 retvalue= x2.getAttribute("real_id"); 00410 } 00411 delete attrbuf; 00412 } 00413 if(retvalue) 00414 break; 00415 } 00416 return retvalue; 00417 } 00418 void tr_twin_ht::deletetransfolder() 00419 { 00420 //delete the folder of the transaction 00421 string cmd; 00422 cmd+="rm -r "; 00423 cmd+=MAINFOLDER; 00424 cmd+=this->trans_folder; 00425 system(cmd); 00426 } 00427 00428 00429 void tr_twin_ht::blockrecord(char* id_rec) 00430 { 00431 00432 srand ( time(NULL) ); 00433 string fname1; 00434 fname1+=MAINFOLDER; 00435 fname1+=real_table->table_folder; 00436 fname1+="/data_"; 00437 fname1+=id_rec; 00438 fname1+=".xml"; 00439 XMLNode x1, x2; 00440 char *buf1=0; 00441 trbl_two: 00442 x1=XMLNode::parseFile(fname1.c_str()); 00443 x2=x1.getChildNode("records"); 00444 00445 00446 buf1=x2.getAttribute("trid"); 00447 if(!buf1){ 00448 //blokiraj 00449 x2.addAttribute("trid", inttostr(this->trans_id)); 00450 x1.writeToFile(fname1.c_str()); 00451 00452 00453 }else{ 00454 if(strcmp(buf1, id_rec)&&strcmp(buf1, "0")){ 00455 //drug e blokiral , 4akaj 00456 usleep(200000+ rand()%800000); 00457 goto trbl_two; 00458 00459 } 00460 //blokiraj 00461 x2.addAttribute("trid", id_rec); 00462 x1.writeToFile(fname1.c_str()); 00463 00464 00465 } 00466 00467 00468 00469 if(buf1) 00470 delete buf1; 00471 00472 00473 00474 00475 } 00476 00477 void tr_twin_ht::unblockrecord(char* id_rec) 00478 { 00479 string fname1; 00480 fname1+=MAINFOLDER; 00481 fname1+=real_table->table_folder; 00482 fname1+="/data_"; 00483 fname1+=id_rec; 00484 fname1+=".xml"; 00485 XMLNode x1, x2; 00486 char *buf1=0; 00487 00488 x1=XMLNode::parseFile(fname1.c_str()); 00489 x2=x1.getChildNode("records"); 00490 x2.updateAttribute("0", "trid", "trid"); 00491 x1.writeToFile(fname1.c_str()); 00492 } 00493 int tr_twin_ht::getMAXID() 00494 { 00495 int i, j; 00496 string fname; 00497 fname=MAINFOLDER; 00498 fname+=this->table_folder; 00499 00500 00501 fname+="/hash_main.xml"; 00502 int rtv=1; 00503 char** freeids=0; 00504 int nids=0; 00505 XMLNode x1, x2, x3, x4; 00506 x1=XMLNode::parseFile(fname.c_str()); 00507 x2=x1.getChildNode("info"); 00508 x3=x2.getChildNode("nrecords"); 00509 x4=x2.getChildNode("deletedids"); 00510 char *buf0=0; 00511 char *buf1=0; 00512 00513 buf0=x3.getText(); 00514 buf1=x4.getText(); 00515 if(buf1){ 00516 if(strlen(buf1)>0){ 00517 this->split(buf1, &nids, &freeids); 00518 rtv=strtoint(freeids[0]); 00519 00520 00521 00522 goto getmid_endl1; 00523 }else{ 00524 00525 } 00526 00527 }else{ 00528 00529 00530 } 00531 rtv=(0x80000000|strtoint(x3.getText()))+1; 00532 00533 getmid_endl1: 00534 00535 00536 if(buf0) 00537 delete buf0; 00538 if(buf1) 00539 delete buf1; 00540 00541 00542 return rtv; 00543 }