BOSS 6.6.4.p01
BESIII Offline Software System
Loading...
Searching...
No Matches
test_build.cxx File Reference
#include <iostream>
#include <string>
#include <cstdlib>
#include "rdbModel/Rdb.h"
#include "rdbModel/RdbException.h"
#include "rdbModel/Management/Manager.h"
#include "rdbModel/Management/XercesBuilder.h"
#include "rdbModel/Db/MysqlConnection.h"
#include "rdbModel/Db/MysqlResults.h"
#include "rdbModel/Tables/Table.h"
#include "rdbModel/Tables/Column.h"
#include "rdbModel/Tables/Datatype.h"
#include "rdbModel/Tables/Assertion.h"
#include "facilities/Util.h"

Go to the source code of this file.

Macros

#define TEST_INSERT
 

Functions

int doInsert (rdbModel::Rdb *con)
 
int doSmartInsert (rdbModel::Rdb *rdb)
 
int doUpdate (rdbModel::Rdb *, int serial)
 
void tryQuick (rdbModel::Table *t, const std::string &colname)
 
int doSupersedes (rdbModel::Rdb *rdb, int serial, int *newSerial)
 
int doSupersede (rdbModel::Rdb *rdb, rdbModel::Row &row, int serial, int *newSerial)
 
int main (int, char **)
 

Macro Definition Documentation

◆ TEST_INSERT

#define TEST_INSERT

Definition at line 19 of file test_build.cxx.

Function Documentation

◆ doInsert()

int doInsert ( rdbModel::Rdb con)

Definition at line 306 of file test_build.cxx.

306 {
307
308 using rdbModel::FieldVal;
309 using rdbModel::Row;
310
311 std::vector<FieldVal> fields;
312 fields.reserve(15);
313
314 fields.push_back(FieldVal("instrument", "LAT"));
315 fields.push_back(FieldVal("calib_type","Test_Gen"));
316 fields.push_back(FieldVal("flavor","berry"));
317 fields.push_back(FieldVal("data_fmt","nonsense"));
318 fields.push_back(FieldVal("vstart","2003-02-01"));
319 fields.push_back(FieldVal("data_size","0"));
320 fields.push_back(FieldVal("locale","phobos"));
321 fields.push_back(FieldVal("completion","ABORT"));
322 fields.push_back(FieldVal("data_ident","$(mycalibs)/test/moreJunk.xml"));
323 fields.push_back(FieldVal("notes",
324 "Absurd test item, setting input_desc to NULL"));
325 fields.push_back(FieldVal("input_desc","", true));
326
327 int serial = 0;
328
329 Row row(fields);
330
331 rdb->insertRow("metadata_v2r1", row, &serial);
332
333 return serial;
334}

Referenced by main().

◆ doSmartInsert()

int doSmartInsert ( rdbModel::Rdb rdb)

Definition at line 336 of file test_build.cxx.

336 {
337 using rdbModel::FieldVal;
338
339 std::vector<FieldVal> fields;
340 fields.reserve(15);
341
342 fields.push_back(FieldVal("instrument", "LAT"));
343 fields.push_back(FieldVal("calib_type", "CAL_Ped"));
344 fields.push_back(FieldVal("flavor", "vanilla"));
345 fields.push_back(FieldVal("proc_level", "PROD"));
346 fields.push_back(FieldVal("completion", "OK"));
347 fields.push_back(FieldVal("data_fmt", "XML"));
348 fields.push_back(FieldVal("fmt_version", "1.1"));
349 fields.push_back(FieldVal("data_ident", "nofile.xml"));
350 fields.push_back(FieldVal("vstart", "2004-01-04"));
351 fields.push_back(FieldVal("vend", "2030-01-01"));
352 fields.push_back(FieldVal("locale", "Oz"));
353 fields.push_back(FieldVal("input_desc", "none"));
354 fields.push_back(FieldVal("notes", "trying out insertLatest"));
355 fields.push_back(FieldVal("prod_end","",true));
356 fields.push_back(FieldVal("input_start","",true));
357 fields.push_back(FieldVal("input_end","",true));
358
359 rdbModel::Row row(fields);
360
361 int serial = 0;
362 try {
363 rdb->insertLatest("metadata_v2r1", row, &serial);
364 }
365 catch (rdbModel::RdbException ex) {
366 std::cerr << "insertLatest failed with message" << ex.getMsg();
367 }
368 return serial;
369}
virtual std::string getMsg()
Definition: RdbException.h:14
int insertLatest(Table *t, Row &row, int *serial=0) const
Definition: Rdb.cxx:72

Referenced by main().

◆ doSupersede()

int doSupersede ( rdbModel::Rdb rdb,
rdbModel::Row row,
int  serial,
int *  newSerial 
)

Definition at line 471 of file test_build.cxx.

472 {
473
474 std::string table("metadata_v2r1");
475 int retVal = -1;
476
477 try {
478 retVal = rdb->supersedeRow(table, row, serial, newSerial);
479 if (retVal) {
480 std::cout << "supersede of row " << serial << " failed with code "
481 << retVal << std::endl;
482 }
483 else {
484 std::cout << "supsersede of row " << serial << " succeeded" << std::endl;
485 }
486 }
487 catch (rdbModel::RdbException ex) {
488 std::cout << "supersede of row " << serial << " failed with exception "
489 << std::endl;
490 std::cout << ex.getMsg() << std::endl;
491 }
492 return retVal;
493}
int supersedeRow(const std::string &tName, Row &row, int oldKey, int *newKey=0) const
Definition: Rdb.cxx:87

Referenced by doSupersedes().

◆ doSupersedes()

int doSupersedes ( rdbModel::Rdb rdb,
int  serial,
int *  newSerial 
)

Definition at line 435 of file test_build.cxx.

435 {
436 using rdbModel::Row;
437 using rdbModel::FieldVal;
438
439 int retVal;
440 int nSuccess = 0;
441 Row row;
442
443 // First put something in row that doesn't belong there
444 row.addField(FieldVal("data_ident","supFile.xml"));
445 row.addField(FieldVal("notes", "this supersede is not supposed to work"));
446 row.addField(FieldVal("instrument", "cello"));
447
448 retVal = doSupersede(rdb, row, serial, newSerial);
449 if (!retVal) nSuccess++;
450
451
452 // Now leave out something necessary
453 row.clear();
454 row.addField(FieldVal("notes", "oops! left out data_ident"));
455
456 retVal = doSupersede(rdb, row, serial, newSerial);
457 if (!retVal) nSuccess++;
458
459 // Now try to do it right!
460 row.clear();
461 row.addField(FieldVal("data_ident", "supFile.xml"));
462 row.addField(FieldVal("notes", "Try supersede with good row input"));
463 retVal = doSupersede(rdb, row, serial, newSerial);
464 if (!retVal) nSuccess++;
465
466 std::cout << "Attempted 3 supersedes; # success = " << nSuccess
467 << std::endl;
468 return nSuccess;
469}
int doSupersede(rdbModel::Rdb *rdb, rdbModel::Row &row, int serial, int *newSerial)
Definition: test_build.cxx:471

Referenced by main().

◆ doUpdate()

int doUpdate ( rdbModel::Rdb rdb,
int  serial 
)

Definition at line 372 of file test_build.cxx.

372 {
374 using rdbModel::Column;
375 using facilities::Util;
376 using rdbModel::FieldVal;
377 using rdbModel::Row;
378
379 // Set up WHERE clause, always the same
380 std::string serialStr;
381 Util::itoa(serial, serialStr);
382 Assertion::Operator* serEquals =
383 new Assertion::Operator(rdbModel::OPTYPEequal, "ser_no",
384 serialStr, rdbModel::FIELDTYPEold,
386
387 Assertion* whereSer = new Assertion(serEquals);
388 // Assertion* whereSer = new Assertion(Assertion::WHENwhere, serEquals);
389
390 // First call an update without any null columns; change notes field
391 // and set data_size to something.
392 /* std::vector<std::string> colNames, values, nullCols; */
393 std::vector<FieldVal> fields;
394
395 fields.push_back(FieldVal("notes", "1st update: set data_size to non-zero value"));
396 fields.push_back(FieldVal("data_size", "883"));
397
398 Row row(fields);
399
400 std::string table("metadata_v2r1");
401
402 unsigned nChange = rdb->updateRows(table, row, whereSer);
403
404 // Now null out data_size
405 fields.clear();
406 fields.push_back(FieldVal("data_size", "", true));
407 fields.push_back(FieldVal("notes", "2nd update: data_size set to NULL"));
408 Row row2(fields);
409
410 nChange += rdb->updateRows(table, row2, whereSer);
411 return nChange;
412}
int updateRows(const std::string &tName, Row &row, Assertion *where) const
Definition: Rdb.cxx:62
@ FIELDTYPEold
Definition: Rdb.h:23
@ FIELDTYPElit
Definition: Rdb.h:22

Referenced by main().

◆ main()

int main ( int  ,
char **   
)

Definition at line 28 of file test_build.cxx.

28 {
30
31 std::string infile("$(RDBMODELROOT)/xml/calib_test.xml");
32
34
36 man->setInputSource(infile);
37
38 // good errcode is 0
39 int errcode = man->build();
40
41 if (errcode) {
42 std::cerr << "Build failed with error code " << errcode << std::endl;
43 return errcode;
44 }
45 rdbModel::Rdb* rdb = man->getRdb();
46
47 rdbModel::Table* t = rdb->getTable("metadata_v2r1");
48
49 tryQuick(t, "ser_no");
50 tryQuick(t, "calib_type");
51 tryQuick(t, "notes");
52 tryQuick(t, "prod_start");
53 tryQuick(t, "vstart");
54
55 rdbModel::Assertion* a = t->getAssertionByName("maySupersede");
56 std::vector<FieldVal> oldFields;
57 oldFields.reserve(10);
58 oldFields.push_back(FieldVal("proc_level", "PROD", false));
59 oldFields.push_back(FieldVal("calib_type", "CAL_Ped", false));
60 oldFields.push_back(FieldVal("ser_no", "17", false));
61 oldFields.push_back(FieldVal("completion", "OK", false));
62 oldFields.push_back(FieldVal("prod_start","", true));
63
64 rdbModel::Row oldRow1(oldFields);
65 rdbModel::Row toBeRow;
66
67 bool checkOld = a->verify(oldRow1, toBeRow);
68
69 std::cout << "Result of verifying 'maySupersede' against oldRow1: "
70 << checkOld << std::endl << std::endl;
71
72 oldFields.clear();
73 oldFields.push_back(FieldVal("proc_level", "DEV", false));
74 oldFields.push_back(FieldVal("calib_type", "CAL_Ped", false));
75 oldFields.push_back(FieldVal("ser_no", "17", false));
76 oldFields.push_back(FieldVal("completion", "OK", false));
77
78 rdbModel::Row oldRow2(oldFields);
79
80 checkOld = a->verify(oldRow2, toBeRow);
81
82 std::cout << "Result of verifying 'maySupersede' against oldRow2: "
83 << checkOld << std::endl << std::endl;
84
85 std::string colMin;
86 std::string colMax;
87
88 rdbModel::Column* serCol = rdb->getColumn("metadata_v2r1", "ser_no");
89 if (serCol) {
90 rdbModel::Datatype* serType = serCol->getDatatype();
91
92 std::cout << "Value of isPrimaryKey() for column ser_no is: "
93 << serCol->isPrimaryKey() << std::endl;
94
95 if (serType->getInterval(colMin, colMax) ) {
96 std::cout << "Min and max for ser_no are " << colMin
97 << ", " << colMax << std::endl;
98 } else {
99 std::cout << "ser_no has no min, max " << std::endl;
100 }
101 }
102 else std::cout << "no such column as 'ser_no' " << std::endl;
103
104 rdbModel::Column* vstartCol = rdb->getColumn("metadata_v2r1", "vstart");
105 if (vstartCol) {
106 rdbModel::Datatype* vstartType = vstartCol->getDatatype();
107
108 if (vstartType->getInterval(colMin, colMax) ) {
109 std::cout << "Min and max for vstart are " << colMin
110 << ", " << colMax << std::endl;
111 } else {
112 std::cout << "vstart has no min, max " << std::endl;
113 }
114 }
115 else std::cout << "no such column as 'vstart' " << std::endl;
116
117 // mostly don't want to run code doing an insert. For times
118 // when we do, must connect as user with INSERT priv.
119#ifdef TEST_INSERT
120 std::string connectfileT("$(RDBMODELROOT)/xml/connect/mysqlTester.xml");
121#else
122 std::string connectfileT("$(RDBMODELROOT)/xml/connect/mysqlSlacT.xml");
123#endif
124
125 // Connect to production database, read only
127
128 std::string connectfile("$(RDBMODELROOT)/xml/connect/mysqlSlac.xml");
129
130 if (!(con->open(connectfile)) ) {
131 std::cerr << "Unable to connect to MySQL database" << std::endl;
132 return -1;
133 }
134
135
136 rdbModel::MATCH match = con->matchSchema(rdb, false);
137
138 switch (match) {
140 std::cout << "XML schema and MySQL database are equivalent!" << std::endl;
141 break;
143 std::cout << "XML schema and MySQL database are compatible" << std::endl;
144 break;
146 std::cout << "XML schema and MySQL database are NOT compatible"
147 << std::endl;
148 return -2;
150 std::cout << "Connection failed while attempting match" << std::endl;
151 return -1;
152 }
153
154
155 // Make a query
156 std::string rq[3];
157 rq[0] ="select * from metadata_v2r1";
158 rq[1] ="select calib_type from metadata_v2r1";
159 rq[2] ="select garbage from metadata_v2r1";
160 for (int i = 0; i < 3; i++) {
161 try {
163 con->dbRequest(rq[i]);
164 if (res) {
165 std::cout << "dbRequest '" << rq[i] << "'" << std::endl;
166 std::cout << "succeeded, returned " << res->getNRows()
167 << " rows" << std::endl;
168 }
169 else {
170 std::cout << "dbRequest '" << rq[i] << "'" << std::endl;
171 std::cout << "succeeded, no returned data expected" << std::endl;
172 }
173 }
174 catch (rdbModel::RdbException ex) {
175 std::cerr << "dbRequest '" << rq[i] << "'" << std::endl;
176 std::cerr <<" failed with error: " << ex.getMsg() << std::endl;
177 std::cerr << "Code " << ex.getCode() << std::endl;
178 }
179 }
180
181
182 // Now try to close connection, then reopen.
183 con->close();
184
185 if (!(con->open(connectfile)) ) {
186 std::cerr << "Unable to connect to MySQL database" << std::endl;
187 return -1;
188 }
189 con->close();
190
191 // Now open with alternate connection file
192 if (!(con->open(connectfileT)) ) {
193 std::cerr << "Unable to connect to MySQL database" << std::endl;
194 return -1;
195 }
196 match = con->matchSchema(rdb);
197
198 // Following will do an insert. To keep from cluttering up the
199 // database, mostly don't execute
200 //
201#ifdef TEST_INSERT
202 bool disable = true;
203 con->disableModify(disable); // so don't really change db
204 int serial = doInsert(rdb);
205 if (serial) {
206 std::cout << "Hallelujah! Inserted new row, serial# "
207 << serial << std::endl;
208 // Try to supersede. Should fail since flavor != "vanilla"
209 /*
210 int newSerial;
211 bool didSup = doSupersedes(rdb, serial, &newSerial);
212 if (didSup) {
213 std::cout << "Supersede of " << serial << " successful." << std::endl;
214 std::cout << "New row is " << newSerial << std::endl;
215 }
216 else {
217 std::cout << "Supersede of " << serial << " failed" << std::endl;
218 }
219 */
220 } else if (disable) { // pick random serial# to check out disabled update
221 serial = 17;
222 }
223 if (serial) {
224 // Now try update
225 /* int nUpdates = doUpdate(con, serial); */
226 int nUpdates = doUpdate(rdb, serial);
227
228 if (nUpdates) {
229 std::cout << "Did " << nUpdates << " on row " << serial
230 << std::endl;
231 }
232 else std::cout << "Failed to update row " << serial << std::endl;
233 }
234 else {
235 std::cout << "Bah, humbug. Insert failed. " << std::endl;
236 }
237
238 serial = doSmartInsert(rdb);
239 if (serial) {
240 std::cout << "Did insertLatest, inserted new row with ser_no = "
241 << serial << std::endl;
242 // Try to supersede. Should fail since flavor != "vanilla"
243 int newSerial;
244 bool didSup = doSupersedes(rdb, serial, &newSerial);
245 if (didSup) {
246 std::cout << "Supersede of " << serial << " successful." << std::endl;
247 std::cout << "New row is " << newSerial << std::endl;
248 }
249 else {
250 std::cout << "Supersede of " << serial << " failed" << std::endl;
251 }
252
253 }
254 else if (!disable) {
255 std::cout << "Bah, humbug. insertLatest failed. " << std::endl;
256 }
257#else
258
259
260 // Check that we can really do something with this connection
261
262 switch (match) {
264 std::cout << "XML schema and MySQL database are equivalent!" << std::endl;
265 break;
267 std::cout << "XML schema and MySQL database are compatible" << std::endl;
268 break;
270 std::cout << "XML schema and MySQL database are NOT compatible"
271 << std::endl;
272 break;
273 // return -2;
275 std::cout << "Connection failed while attempting match" << std::endl;
276 return -1;
277 }
278
279 if (match == rdbModel::MATCHfail) { // try again without dbname match
280 match = con->matchSchema(rdb, false);
281
282 switch (match) {
284 std::cout << "XML schema and MySQL database are equivalent!"
285 << std::endl;
286 break;
288 std::cout << "XML schema and MySQL database are compatible" << std::endl;
289 break;
291 std::cout << "XML schema and MySQL database are NOT compatible"
292 << std::endl;
293 // return -2;
295 std::cout << "Connection failed while attempting match" << std::endl;
296 return -1;
297 }
298
299 }
300#endif
301
302 return 0;
303}
bool isPrimaryKey() const
Definition: Column.h:84
Datatype * getDatatype() const
Definition: Column.h:63
bool getInterval(std::string &min, std::string &max)
Definition: Datatype.cxx:154
Rdb * getRdb()
Definition: Manager.h:48
void setInputSource(std::string pname)
Definition: Manager.h:51
void setBuilder(Builder *b)
Definition: Manager.cxx:37
static Manager * getManager()
Definition: Manager.cxx:24
virtual bool open(const std::string &host, const std::string &userid, const std::string &password, const std::string &dbName)
virtual ResultHandle * dbRequest(const std::string &request)
virtual void disableModify(bool disable)
virtual MATCH matchSchema(Rdb *rdb, bool matchDbName=true)
virtual int getCode() const
Definition: RdbException.h:17
Table * getTable(const std::string &name) const
Definition: Rdb.cxx:16
Column * getColumn(const std::string &tableName, const std::string &colName) const
Definition: Rdb.cxx:25
virtual unsigned int getNRows() const =0
Return number of rows in results.
@ MATCHequivalent
Definition: Connection.h:26
@ MATCHnoConnection
Definition: Connection.h:29
@ MATCHfail
Definition: Connection.h:28
@ MATCHcompatible
Definition: Connection.h:27
int t()
Definition: t.c:1
int doInsert(rdbModel::Rdb *con)
Definition: test_build.cxx:306
int doSmartInsert(rdbModel::Rdb *rdb)
Definition: test_build.cxx:336
void tryQuick(rdbModel::Table *t, const std::string &colname)
Definition: test_build.cxx:414
int doSupersedes(rdbModel::Rdb *rdb, int serial, int *newSerial)
Definition: test_build.cxx:435
int doUpdate(rdbModel::Rdb *, int serial)
Definition: test_build.cxx:372

◆ tryQuick()

void tryQuick ( rdbModel::Table t,
const std::string &  colname 
)

Definition at line 414 of file test_build.cxx.

414 {
415 // rdbModel::Column* cQuick = t->getQuick(colname);
416 rdbModel::Column* col = t->getColumnByName(colname);
417
418 if (!col) {
419 std::cerr << colname << " not found by getQuick" << std::endl;
420 return;
421 }
422
423 std::string name = col->getName();
424 if (colname.compare(name) != 0) {
425 std::cerr << "Instead of " << colname << ", getColumnByName found "
426 << name << std::endl;
427 }
428
429 else {
430 std::cout << "getColumnByName found correct column with name " << colname
431 << std::endl;
432 }
433}
const std::string & getName() const
Definition: Column.h:56

Referenced by main().