GDBMS 1.0
GDBMS_for_documentation/tr_twin_ht.cpp
Go to the documentation of this file.
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 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines