/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Calibration/rdbModel/rdbModel-00-01-01/src/test/test_build.cxx

Go to the documentation of this file.
00001 // $Header: /bes/bes/BossCvs/Calibration/rdbModel/src/test/test_build.cxx,v 1.1.1.1 2005/10/17 06:10:53 maqm Exp $
00002 // Test program for rdbModel primitive buiding blocks
00003 
00004 #include <iostream>
00005 #include <string>
00006 #include <cstdlib>
00007 #include "rdbModel/Rdb.h"
00008 #include "rdbModel/RdbException.h"
00009 #include "rdbModel/Management/Manager.h"
00010 #include "rdbModel/Management/XercesBuilder.h"
00011 #include "rdbModel/Db/MysqlConnection.h"
00012 #include "rdbModel/Db/MysqlResults.h"
00013 #include "rdbModel/Tables/Table.h"
00014 #include "rdbModel/Tables/Column.h"
00015 #include "rdbModel/Tables/Datatype.h"
00016 #include "rdbModel/Tables/Assertion.h"
00017 #include "facilities/Util.h"
00018 
00019 #define TEST_INSERT
00020 
00021 int doInsert(rdbModel::Rdb* con);
00022 int doSmartInsert(rdbModel::Rdb* rdb);
00023 int doUpdate(rdbModel::Rdb*, int serial);
00024 void tryQuick(rdbModel::Table* t, const std::string& colname);
00025 int   doSupersedes(rdbModel::Rdb* rdb, int serial, int* newSerial);
00026 int   doSupersede(rdbModel::Rdb* rdb, rdbModel::Row& row, 
00027                   int serial, int* newSerial);
00028 int main(int, char**) {
00029   using rdbModel::FieldVal;
00030 
00031   std::string infile("$(RDBMODELROOT)/xml/calib_test.xml");
00032 
00033   rdbModel::Manager* man = rdbModel::Manager::getManager();
00034 
00035   man->setBuilder(new rdbModel::XercesBuilder);
00036   man->setInputSource(infile);
00037 
00038   // good errcode is 0
00039   int errcode = man->build();
00040 
00041   if (errcode) {
00042     std::cerr << "Build failed with error code " << errcode << std::endl;
00043     return errcode;
00044   }
00045   rdbModel::Rdb* rdb = man->getRdb();
00046 
00047   rdbModel::Table* t = rdb->getTable("metadata_v2r1");
00048 
00049   tryQuick(t, "ser_no");
00050   tryQuick(t, "calib_type");
00051   tryQuick(t, "notes");
00052   tryQuick(t, "prod_start");
00053   tryQuick(t, "vstart");
00054 
00055   rdbModel::Assertion* a = t->getAssertionByName("maySupersede");
00056   std::vector<FieldVal> oldFields;
00057   oldFields.reserve(10);
00058   oldFields.push_back(FieldVal("proc_level", "PROD", false));
00059   oldFields.push_back(FieldVal("calib_type", "CAL_Ped", false));
00060   oldFields.push_back(FieldVal("ser_no", "17", false));
00061   oldFields.push_back(FieldVal("completion", "OK", false));
00062   oldFields.push_back(FieldVal("prod_start","", true));
00063 
00064   rdbModel::Row oldRow1(oldFields);
00065   rdbModel::Row toBeRow;
00066 
00067   bool checkOld = a->verify(oldRow1, toBeRow);
00068   
00069   std::cout << "Result of verifying 'maySupersede' against oldRow1: " 
00070             << checkOld << std::endl << std::endl;
00071 
00072   oldFields.clear();
00073   oldFields.push_back(FieldVal("proc_level", "DEV", false));
00074   oldFields.push_back(FieldVal("calib_type", "CAL_Ped", false));
00075   oldFields.push_back(FieldVal("ser_no", "17", false));
00076   oldFields.push_back(FieldVal("completion", "OK", false));
00077   
00078   rdbModel::Row oldRow2(oldFields);
00079 
00080   checkOld = a->verify(oldRow2, toBeRow);
00081   
00082   std::cout << "Result of verifying 'maySupersede' against oldRow2: " 
00083             << checkOld << std::endl << std::endl;
00084 
00085   std::string colMin;
00086   std::string colMax;
00087   
00088   rdbModel::Column* serCol = rdb->getColumn("metadata_v2r1", "ser_no");
00089   if (serCol) {
00090     rdbModel::Datatype* serType = serCol->getDatatype();
00091 
00092     std::cout << "Value of isPrimaryKey() for column ser_no is: " 
00093               << serCol->isPrimaryKey() << std::endl;
00094 
00095     if (serType->getInterval(colMin, colMax) ) {
00096       std::cout << "Min and max for ser_no are " << colMin 
00097                 << ", " << colMax << std::endl;
00098     }  else {
00099       std::cout << "ser_no has no min, max " << std::endl;
00100     }
00101   }
00102   else std::cout << "no such column as 'ser_no' " << std::endl;
00103 
00104   rdbModel::Column* vstartCol = rdb->getColumn("metadata_v2r1", "vstart");
00105   if (vstartCol) {
00106     rdbModel::Datatype* vstartType = vstartCol->getDatatype();
00107 
00108     if (vstartType->getInterval(colMin, colMax) ) {
00109       std::cout << "Min and max for vstart are " << colMin 
00110                 << ", " << colMax << std::endl;
00111     }  else {
00112       std::cout << "vstart has no min, max " << std::endl;
00113     }
00114   }
00115   else std::cout << "no such column as 'vstart' " << std::endl;
00116 
00117   // mostly don't want to run code doing an insert.  For times
00118   // when we do, must connect as user with INSERT priv.
00119 #ifdef TEST_INSERT
00120   std::string connectfileT("$(RDBMODELROOT)/xml/connect/mysqlTester.xml");
00121 #else
00122   std::string connectfileT("$(RDBMODELROOT)/xml/connect/mysqlSlacT.xml");
00123 #endif
00124   
00125   // Connect to production database, read only
00126   rdbModel::MysqlConnection* con = new rdbModel::MysqlConnection();
00127 
00128   std::string connectfile("$(RDBMODELROOT)/xml/connect/mysqlSlac.xml");
00129 
00130   if (!(con->open(connectfile)) ) {
00131     std::cerr << "Unable to connect to MySQL database" << std::endl;
00132     return -1;
00133   }
00134 
00135 
00136   rdbModel::MATCH match = con->matchSchema(rdb, false);
00137 
00138   switch (match) {
00139   case rdbModel::MATCHequivalent:
00140     std::cout << "XML schema and MySQL database are equivalent!" << std::endl;
00141     break;
00142   case rdbModel::MATCHcompatible:
00143     std::cout << "XML schema and MySQL database are compatible" << std::endl;
00144     break;
00145   case rdbModel::MATCHfail:
00146     std::cout << "XML schema and MySQL database are NOT compatible" 
00147               << std::endl;
00148     return -2;
00149   case rdbModel::MATCHnoConnection:
00150     std::cout << "Connection failed while attempting match" << std::endl;
00151     return -1;
00152   }
00153 
00154 
00155   // Make a query
00156   std::string rq[3];
00157   rq[0] ="select * from metadata_v2r1";
00158   rq[1] ="select calib_type from metadata_v2r1";
00159   rq[2] ="select garbage from metadata_v2r1";
00160   for (int i = 0; i < 3; i++) {
00161     try {
00162       rdbModel::ResultHandle* res = 
00163         con->dbRequest(rq[i]);
00164       if (res) {
00165         std::cout << "dbRequest '" << rq[i] << "'" << std::endl; 
00166         std::cout << "succeeded, returned " << res->getNRows() 
00167                   << " rows" << std::endl;
00168       }
00169       else {
00170         std::cout << "dbRequest '" << rq[i] << "'" << std::endl; 
00171         std::cout << "succeeded, no returned data expected" << std::endl;
00172       }
00173     }
00174     catch (rdbModel::RdbException ex) {
00175       std::cerr << "dbRequest '" <<  rq[i] << "'" << std::endl; 
00176       std::cerr <<" failed with error: " << ex.getMsg() << std::endl;
00177       std::cerr << "Code " << ex.getCode() << std::endl;
00178     }
00179   }
00180 
00181 
00182   // Now try to close connection, then reopen.
00183   con->close();
00184 
00185   if (!(con->open(connectfile)) ) {
00186     std::cerr << "Unable to connect to MySQL database" << std::endl;
00187     return -1;
00188   }
00189   con->close();
00190 
00191   // Now open with alternate connection file
00192   if (!(con->open(connectfileT)) ) {
00193     std::cerr << "Unable to connect to MySQL database" << std::endl;
00194     return -1;
00195   }
00196   match = con->matchSchema(rdb);
00197 
00198   // Following will do an insert.  To keep from cluttering up the
00199   // database, mostly don't execute
00200   //  
00201 #ifdef TEST_INSERT
00202   bool disable = true;
00203   con->disableModify(disable);     // so don't really change db
00204   int serial = doInsert(rdb);
00205   if (serial) {
00206     std::cout << "Hallelujah!  Inserted new row, serial# " 
00207               << serial  << std::endl;
00208     // Try to supersede.  Should fail since flavor != "vanilla"
00209     /*
00210     int newSerial;
00211     bool didSup = doSupersedes(rdb, serial, &newSerial);
00212     if (didSup) {
00213       std::cout << "Supersede of " << serial << " successful." << std::endl;
00214       std::cout << "New row is " << newSerial << std::endl;
00215     }
00216     else {
00217       std::cout << "Supersede of " << serial << " failed" << std::endl;
00218     }
00219     */
00220   } else if (disable) {  // pick random serial# to check out disabled update
00221     serial = 17;
00222   }
00223   if (serial) {
00224     // Now try update
00225     /*    int nUpdates = doUpdate(con, serial);  */
00226     int nUpdates = doUpdate(rdb, serial);
00227 
00228     if (nUpdates) {
00229       std::cout << "Did " << nUpdates << " on row " << serial
00230                 << std::endl;
00231     }
00232     else std::cout << "Failed to update row " << serial << std::endl;
00233   }
00234   else {
00235     std::cout << "Bah, humbug.  Insert failed. " << std::endl;
00236   }
00237 
00238   serial = doSmartInsert(rdb);
00239   if (serial) {
00240     std::cout << "Did insertLatest, inserted new row with ser_no = " 
00241               << serial << std::endl;
00242     // Try to supersede.  Should fail since flavor != "vanilla"
00243     int newSerial;
00244     bool didSup = doSupersedes(rdb, serial, &newSerial);
00245     if (didSup) {
00246       std::cout << "Supersede of " << serial << " successful." << std::endl;
00247       std::cout << "New row is " << newSerial << std::endl;
00248     }
00249     else {
00250       std::cout << "Supersede of " << serial << " failed" << std::endl;
00251     }
00252 
00253   }
00254   else if (!disable) {
00255     std::cout << "Bah, humbug.  insertLatest failed. " << std::endl;
00256   }
00257 #else
00258 
00259 
00260   // Check that we can really do something with this connection
00261 
00262   switch (match) {
00263   case rdbModel::MATCHequivalent:
00264     std::cout << "XML schema and MySQL database are equivalent!" << std::endl;
00265     break;
00266   case rdbModel::MATCHcompatible:
00267     std::cout << "XML schema and MySQL database are compatible" << std::endl;
00268     break;
00269   case rdbModel::MATCHfail:
00270     std::cout << "XML schema and MySQL database are NOT compatible" 
00271               << std::endl;
00272     break;
00273     //    return -2;
00274   case rdbModel::MATCHnoConnection:
00275     std::cout << "Connection failed while attempting match" << std::endl;
00276     return -1;
00277   }
00278 
00279   if (match == rdbModel::MATCHfail) { // try again without dbname match
00280     match = con->matchSchema(rdb, false);
00281 
00282     switch (match) {
00283     case rdbModel::MATCHequivalent:
00284       std::cout << "XML schema and MySQL database are equivalent!" 
00285                 << std::endl;
00286       break;
00287     case rdbModel::MATCHcompatible:
00288       std::cout << "XML schema and MySQL database are compatible" << std::endl;
00289       break;
00290     case rdbModel::MATCHfail:
00291       std::cout << "XML schema and MySQL database are NOT compatible" 
00292                 << std::endl;
00293       //    return -2;
00294     case rdbModel::MATCHnoConnection:
00295       std::cout << "Connection failed while attempting match" << std::endl;
00296       return -1;
00297     }
00298 
00299   }
00300 #endif
00301 
00302   return 0;
00303 }
00304 
00305 // int doInsert(rdbModel::Connection* con) {
00306 int doInsert(rdbModel::Rdb* rdb) {
00307   
00308   using rdbModel::FieldVal;
00309   using rdbModel::Row;
00310 
00311   std::vector<FieldVal> fields;
00312   fields.reserve(15);
00313 
00314   fields.push_back(FieldVal("instrument", "LAT"));
00315   fields.push_back(FieldVal("calib_type","Test_Gen"));
00316   fields.push_back(FieldVal("flavor","berry"));
00317   fields.push_back(FieldVal("data_fmt","nonsense"));
00318   fields.push_back(FieldVal("vstart","2003-02-01"));
00319   fields.push_back(FieldVal("data_size","0"));
00320   fields.push_back(FieldVal("locale","phobos"));
00321   fields.push_back(FieldVal("completion","ABORT"));
00322   fields.push_back(FieldVal("data_ident","$(mycalibs)/test/moreJunk.xml"));
00323   fields.push_back(FieldVal("notes", 
00324                             "Absurd test item, setting input_desc to NULL"));
00325   fields.push_back(FieldVal("input_desc","", true));
00326 
00327   int  serial = 0;
00328   
00329   Row row(fields);
00330 
00331   rdb->insertRow("metadata_v2r1", row, &serial);
00332     
00333   return serial;
00334 }
00335 /*            start here */
00336 int doSmartInsert(rdbModel::Rdb* rdb) {
00337   using rdbModel::FieldVal;
00338 
00339   std::vector<FieldVal> fields;
00340   fields.reserve(15);
00341 
00342   fields.push_back(FieldVal("instrument", "LAT"));
00343   fields.push_back(FieldVal("calib_type", "CAL_Ped"));
00344   fields.push_back(FieldVal("flavor", "vanilla"));
00345   fields.push_back(FieldVal("proc_level", "PROD"));
00346   fields.push_back(FieldVal("completion", "OK"));
00347   fields.push_back(FieldVal("data_fmt", "XML"));
00348   fields.push_back(FieldVal("fmt_version", "1.1"));
00349   fields.push_back(FieldVal("data_ident", "nofile.xml"));
00350   fields.push_back(FieldVal("vstart", "2004-01-04"));
00351   fields.push_back(FieldVal("vend", "2030-01-01"));
00352   fields.push_back(FieldVal("locale", "Oz"));
00353   fields.push_back(FieldVal("input_desc", "none"));
00354   fields.push_back(FieldVal("notes", "trying out insertLatest"));
00355   fields.push_back(FieldVal("prod_end","",true));
00356   fields.push_back(FieldVal("input_start","",true));
00357   fields.push_back(FieldVal("input_end","",true));
00358 
00359   rdbModel::Row row(fields);
00360 
00361   int  serial = 0;
00362   try {
00363     rdb->insertLatest("metadata_v2r1", row, &serial);
00364   }
00365   catch (rdbModel::RdbException ex) {
00366     std::cerr << "insertLatest failed with message" << ex.getMsg();
00367   }
00368   return serial;
00369 }
00370 
00371 // int doUpdate(rdbModel::Connection* con, int serial) {
00372 int doUpdate(rdbModel::Rdb* rdb, int serial) {
00373   using rdbModel::Assertion;
00374   using rdbModel::Column;
00375   using facilities::Util;
00376   using rdbModel::FieldVal;
00377   using rdbModel::Row;
00378 
00379   // Set up WHERE clause, always the same
00380   std::string serialStr;
00381   Util::itoa(serial, serialStr);
00382   Assertion::Operator* serEquals = 
00383     new Assertion::Operator(rdbModel::OPTYPEequal, "ser_no",
00384                             serialStr, rdbModel::FIELDTYPEold, 
00385                             rdbModel::FIELDTYPElit);
00386 
00387   Assertion* whereSer = new Assertion(serEquals);
00388   //  Assertion* whereSer = new Assertion(Assertion::WHENwhere, serEquals);
00389 
00390   // First call an update without any null columns; change notes field
00391   // and set data_size to something.
00392   /*  std::vector<std::string> colNames, values, nullCols; */
00393   std::vector<FieldVal> fields;
00394   
00395   fields.push_back(FieldVal("notes", "1st update: set data_size to non-zero value"));
00396   fields.push_back(FieldVal("data_size", "883"));
00397   
00398   Row row(fields);
00399 
00400   std::string table("metadata_v2r1");
00401 
00402   unsigned nChange = rdb->updateRows(table, row, whereSer);
00403 
00404   // Now null out data_size
00405   fields.clear();
00406   fields.push_back(FieldVal("data_size", "", true));
00407   fields.push_back(FieldVal("notes", "2nd update: data_size set to NULL"));
00408   Row row2(fields);
00409 
00410   nChange += rdb->updateRows(table, row2, whereSer);
00411   return nChange;
00412 }
00413 
00414 void tryQuick(rdbModel::Table* t, const std::string& colname) {
00415   //  rdbModel::Column* cQuick = t->getQuick(colname);
00416   rdbModel::Column* col = t->getColumnByName(colname);
00417 
00418   if (!col) {
00419     std::cerr << colname << " not found by getQuick" << std::endl;
00420     return;
00421   }
00422 
00423   std::string name = col->getName();
00424   if (colname.compare(name) != 0) {
00425     std::cerr << "Instead of " << colname << ", getColumnByName found " 
00426     << name << std::endl;
00427   }
00428 
00429   else {
00430     std::cout << "getColumnByName found correct column with name " << colname 
00431               << std::endl;
00432   }
00433 }
00434 
00435 int  doSupersedes(rdbModel::Rdb* rdb, int serial, int* newSerial) {
00436   using rdbModel::Row;
00437   using rdbModel::FieldVal;
00438 
00439   int retVal;
00440   int nSuccess = 0;
00441   Row row;
00442 
00443   // First put something in row that doesn't belong there
00444   row.addField(FieldVal("data_ident","supFile.xml"));
00445   row.addField(FieldVal("notes", "this supersede is not supposed to work"));
00446   row.addField(FieldVal("instrument", "cello"));
00447 
00448   retVal = doSupersede(rdb, row, serial, newSerial);
00449   if (!retVal) nSuccess++;
00450 
00451 
00452   // Now leave out something necessary
00453   row.clear();
00454   row.addField(FieldVal("notes", "oops!  left out data_ident"));
00455 
00456   retVal = doSupersede(rdb, row, serial, newSerial);
00457   if (!retVal) nSuccess++;
00458 
00459   // Now try to do it right!
00460   row.clear();
00461   row.addField(FieldVal("data_ident", "supFile.xml"));
00462   row.addField(FieldVal("notes", "Try supersede with good row input"));
00463   retVal = doSupersede(rdb, row, serial, newSerial);
00464   if (!retVal) nSuccess++;
00465 
00466   std::cout << "Attempted 3 supersedes; # success = " << nSuccess
00467             << std::endl;
00468   return nSuccess;
00469 }
00470 
00471 int  doSupersede(rdbModel::Rdb* rdb, rdbModel::Row& row, int serial, 
00472                   int* newSerial) {
00473 
00474   std::string table("metadata_v2r1");
00475   int retVal = -1;
00476 
00477   try {
00478     retVal = rdb->supersedeRow(table, row, serial, newSerial);
00479     if (retVal) {
00480       std::cout << "supersede of row " << serial << " failed with code " 
00481                 << retVal << std::endl;
00482     }
00483     else {
00484       std::cout << "supsersede of row " << serial << " succeeded" << std::endl;
00485     }
00486   }
00487   catch (rdbModel::RdbException ex) {
00488     std::cout << "supersede of row " << serial << " failed with exception " 
00489               << std::endl;
00490     std::cout << ex.getMsg() << std::endl;
00491   }
00492   return retVal;
00493 }

Generated on Tue Nov 29 22:57:57 2016 for BOSS_7.0.2 by  doxygen 1.4.7