00001
00002
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
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
00118
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
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
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
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
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
00199
00200
00201 #ifdef TEST_INSERT
00202 bool disable = true;
00203 con->disableModify(disable);
00204 int serial = doInsert(rdb);
00205 if (serial) {
00206 std::cout << "Hallelujah! Inserted new row, serial# "
00207 << serial << std::endl;
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 } else if (disable) {
00221 serial = 17;
00222 }
00223 if (serial) {
00224
00225
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
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
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
00274 case rdbModel::MATCHnoConnection:
00275 std::cout << "Connection failed while attempting match" << std::endl;
00276 return -1;
00277 }
00278
00279 if (match == rdbModel::MATCHfail) {
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
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
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
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
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
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
00389
00390
00391
00392
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
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
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
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
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
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 }