BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
test_build.cxx
Go to the documentation of this file.
1// $Header: /bes/bes/BossCvs/Calibration/rdbModel/src/test/test_build.cxx,v 1.1.1.1 2005/10/17
2// 06:10:53 maqm Exp $ Test program for rdbModel primitive buiding blocks
3
4#include "facilities/Util.h"
5#include "rdbModel/Db/MysqlConnection.h"
6#include "rdbModel/Db/MysqlResults.h"
7#include "rdbModel/Management/Manager.h"
8#include "rdbModel/Management/XercesBuilder.h"
9#include "rdbModel/Rdb.h"
10#include "rdbModel/RdbException.h"
11#include "rdbModel/Tables/Assertion.h"
12#include "rdbModel/Tables/Column.h"
13#include "rdbModel/Tables/Datatype.h"
14#include "rdbModel/Tables/Table.h"
15#include <cstdlib>
16#include <iostream>
17#include <string>
18
19#define TEST_INSERT
20
21int doInsert( rdbModel::Rdb* con );
23int doUpdate( rdbModel::Rdb*, int serial );
24void tryQuick( rdbModel::Table* t, const std::string& colname );
25int doSupersedes( rdbModel::Rdb* rdb, int serial, int* newSerial );
26int doSupersede( rdbModel::Rdb* rdb, rdbModel::Row& row, int serial, int* newSerial );
27int main( int, char** ) {
29
30 std::string infile( "$(RDBMODELROOT)/xml/calib_test.xml" );
31
33
35 man->setInputSource( infile );
36
37 // good errcode is 0
38 int errcode = man->build();
39
40 if ( errcode )
41 {
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: " << checkOld << std::endl
70 << 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: " << checkOld << std::endl
83 << 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 {
91 rdbModel::Datatype* serType = serCol->getDatatype();
92
93 std::cout << "Value of isPrimaryKey() for column ser_no is: " << serCol->isPrimaryKey()
94 << std::endl;
95
96 if ( serType->getInterval( colMin, colMax ) )
97 { std::cout << "Min and max for ser_no are " << colMin << ", " << colMax << std::endl; }
98 else { std::cout << "ser_no has no min, max " << std::endl; }
99 }
100 else std::cout << "no such column as 'ser_no' " << std::endl;
101
102 rdbModel::Column* vstartCol = rdb->getColumn( "metadata_v2r1", "vstart" );
103 if ( vstartCol )
104 {
105 rdbModel::Datatype* vstartType = vstartCol->getDatatype();
106
107 if ( vstartType->getInterval( colMin, colMax ) )
108 { std::cout << "Min and max for vstart are " << colMin << ", " << colMax << std::endl; }
109 else { std::cout << "vstart has no min, max " << std::endl; }
110 }
111 else std::cout << "no such column as 'vstart' " << std::endl;
112
113 // mostly don't want to run code doing an insert. For times
114 // when we do, must connect as user with INSERT priv.
115#ifdef TEST_INSERT
116 std::string connectfileT( "$(RDBMODELROOT)/xml/connect/mysqlTester.xml" );
117#else
118 std::string connectfileT( "$(RDBMODELROOT)/xml/connect/mysqlSlacT.xml" );
119#endif
120
121 // Connect to production database, read only
123
124 std::string connectfile( "$(RDBMODELROOT)/xml/connect/mysqlSlac.xml" );
125
126 if ( !( con->open( connectfile ) ) )
127 {
128 std::cerr << "Unable to connect to MySQL database" << std::endl;
129 return -1;
130 }
131
132 rdbModel::MATCH match = con->matchSchema( rdb, false );
133
134 switch ( match )
135 {
137 std::cout << "XML schema and MySQL database are equivalent!" << std::endl;
138 break;
140 std::cout << "XML schema and MySQL database are compatible" << std::endl;
141 break;
143 std::cout << "XML schema and MySQL database are NOT compatible" << std::endl;
144 return -2;
146 std::cout << "Connection failed while attempting match" << std::endl;
147 return -1;
148 }
149
150 // Make a query
151 std::string rq[3];
152 rq[0] = "select * from metadata_v2r1";
153 rq[1] = "select calib_type from metadata_v2r1";
154 rq[2] = "select garbage from metadata_v2r1";
155 for ( int i = 0; i < 3; i++ )
156 {
157 try
158 {
159 rdbModel::ResultHandle* res = con->dbRequest( rq[i] );
160 if ( res )
161 {
162 std::cout << "dbRequest '" << rq[i] << "'" << std::endl;
163 std::cout << "succeeded, returned " << res->getNRows() << " rows" << std::endl;
164 }
165 else
166 {
167 std::cout << "dbRequest '" << rq[i] << "'" << std::endl;
168 std::cout << "succeeded, no returned data expected" << std::endl;
169 }
170 } catch ( rdbModel::RdbException ex )
171 {
172 std::cerr << "dbRequest '" << rq[i] << "'" << std::endl;
173 std::cerr << " failed with error: " << ex.getMsg() << std::endl;
174 std::cerr << "Code " << ex.getCode() << std::endl;
175 }
176 }
177
178 // Now try to close connection, then reopen.
179 con->close();
180
181 if ( !( con->open( connectfile ) ) )
182 {
183 std::cerr << "Unable to connect to MySQL database" << std::endl;
184 return -1;
185 }
186 con->close();
187
188 // Now open with alternate connection file
189 if ( !( con->open( connectfileT ) ) )
190 {
191 std::cerr << "Unable to connect to MySQL database" << std::endl;
192 return -1;
193 }
194 match = con->matchSchema( rdb );
195
196 // Following will do an insert. To keep from cluttering up the
197 // database, mostly don't execute
198 //
199#ifdef TEST_INSERT
200 bool disable = true;
201 con->disableModify( disable ); // so don't really change db
202 int serial = doInsert( rdb );
203 if ( serial )
204 {
205 std::cout << "Hallelujah! Inserted new row, serial# " << serial << std::endl;
206 // Try to supersede. Should fail since flavor != "vanilla"
207 /*
208 int newSerial;
209 bool didSup = doSupersedes(rdb, serial, &newSerial);
210 if (didSup) {
211 std::cout << "Supersede of " << serial << " successful." << std::endl;
212 std::cout << "New row is " << newSerial << std::endl;
213 }
214 else {
215 std::cout << "Supersede of " << serial << " failed" << std::endl;
216 }
217 */
218 }
219 else if ( disable )
220 { // pick random serial# to check out disabled update
221 serial = 17;
222 }
223 if ( serial )
224 {
225 // Now try update
226 /* int nUpdates = doUpdate(con, serial); */
227 int nUpdates = doUpdate( rdb, serial );
228
229 if ( nUpdates ) { std::cout << "Did " << nUpdates << " on row " << serial << std::endl; }
230 else std::cout << "Failed to update row " << serial << std::endl;
231 }
232 else { std::cout << "Bah, humbug. Insert failed. " << std::endl; }
233
234 serial = doSmartInsert( rdb );
235 if ( serial )
236 {
237 std::cout << "Did insertLatest, inserted new row with ser_no = " << serial << std::endl;
238 // Try to supersede. Should fail since flavor != "vanilla"
239 int newSerial;
240 bool didSup = doSupersedes( rdb, serial, &newSerial );
241 if ( didSup )
242 {
243 std::cout << "Supersede of " << serial << " successful." << std::endl;
244 std::cout << "New row is " << newSerial << std::endl;
245 }
246 else { std::cout << "Supersede of " << serial << " failed" << std::endl; }
247 }
248 else if ( !disable ) { std::cout << "Bah, humbug. insertLatest failed. " << std::endl; }
249#else
250
251 // Check that we can really do something with this connection
252
253 switch ( match )
254 {
256 std::cout << "XML schema and MySQL database are equivalent!" << std::endl;
257 break;
259 std::cout << "XML schema and MySQL database are compatible" << std::endl;
260 break;
262 std::cout << "XML schema and MySQL database are NOT compatible" << std::endl;
263 break;
264 // return -2;
266 std::cout << "Connection failed while attempting match" << std::endl;
267 return -1;
268 }
269
270 if ( match == rdbModel::MATCHfail )
271 { // try again without dbname match
272 match = con->matchSchema( rdb, false );
273
274 switch ( match )
275 {
277 std::cout << "XML schema and MySQL database are equivalent!" << std::endl;
278 break;
280 std::cout << "XML schema and MySQL database are compatible" << std::endl;
281 break;
283 std::cout << "XML schema and MySQL database are NOT compatible" << std::endl;
284 // return -2;
286 std::cout << "Connection failed while attempting match" << std::endl;
287 return -1;
288 }
289 }
290#endif
291
292 return 0;
293}
294
295// int doInsert(rdbModel::Connection* con) {
297
298 using rdbModel::FieldVal;
299 using rdbModel::Row;
300
301 std::vector<FieldVal> fields;
302 fields.reserve( 15 );
303
304 fields.push_back( FieldVal( "instrument", "LAT" ) );
305 fields.push_back( FieldVal( "calib_type", "Test_Gen" ) );
306 fields.push_back( FieldVal( "flavor", "berry" ) );
307 fields.push_back( FieldVal( "data_fmt", "nonsense" ) );
308 fields.push_back( FieldVal( "vstart", "2003-02-01" ) );
309 fields.push_back( FieldVal( "data_size", "0" ) );
310 fields.push_back( FieldVal( "locale", "phobos" ) );
311 fields.push_back( FieldVal( "completion", "ABORT" ) );
312 fields.push_back( FieldVal( "data_ident", "$(mycalibs)/test/moreJunk.xml" ) );
313 fields.push_back( FieldVal( "notes", "Absurd test item, setting input_desc to NULL" ) );
314 fields.push_back( FieldVal( "input_desc", "", true ) );
315
316 int serial = 0;
317
318 Row row( fields );
319
320 rdb->insertRow( "metadata_v2r1", row, &serial );
321
322 return serial;
323}
324/* start here */
326 using rdbModel::FieldVal;
327
328 std::vector<FieldVal> fields;
329 fields.reserve( 15 );
330
331 fields.push_back( FieldVal( "instrument", "LAT" ) );
332 fields.push_back( FieldVal( "calib_type", "CAL_Ped" ) );
333 fields.push_back( FieldVal( "flavor", "vanilla" ) );
334 fields.push_back( FieldVal( "proc_level", "PROD" ) );
335 fields.push_back( FieldVal( "completion", "OK" ) );
336 fields.push_back( FieldVal( "data_fmt", "XML" ) );
337 fields.push_back( FieldVal( "fmt_version", "1.1" ) );
338 fields.push_back( FieldVal( "data_ident", "nofile.xml" ) );
339 fields.push_back( FieldVal( "vstart", "2004-01-04" ) );
340 fields.push_back( FieldVal( "vend", "2030-01-01" ) );
341 fields.push_back( FieldVal( "locale", "Oz" ) );
342 fields.push_back( FieldVal( "input_desc", "none" ) );
343 fields.push_back( FieldVal( "notes", "trying out insertLatest" ) );
344 fields.push_back( FieldVal( "prod_end", "", true ) );
345 fields.push_back( FieldVal( "input_start", "", true ) );
346 fields.push_back( FieldVal( "input_end", "", true ) );
347
348 rdbModel::Row row( fields );
349
350 int serial = 0;
351 try
352 { rdb->insertLatest( "metadata_v2r1", row, &serial ); } catch ( rdbModel::RdbException ex )
353 { std::cerr << "insertLatest failed with message" << ex.getMsg(); }
354 return serial;
355}
356
357// int doUpdate(rdbModel::Connection* con, int serial) {
358int doUpdate( rdbModel::Rdb* rdb, int serial ) {
359 using facilities::Util;
361 using rdbModel::Column;
362 using rdbModel::FieldVal;
363 using rdbModel::Row;
364
365 // Set up WHERE clause, always the same
366 std::string serialStr;
367 Util::itoa( serial, serialStr );
368 Assertion::Operator* serEquals =
369 new Assertion::Operator( rdbModel::OPTYPEequal, "ser_no", serialStr,
371
372 Assertion* whereSer = new Assertion( serEquals );
373 // Assertion* whereSer = new Assertion(Assertion::WHENwhere, serEquals);
374
375 // First call an update without any null columns; change notes field
376 // and set data_size to something.
377 /* std::vector<std::string> colNames, values, nullCols; */
378 std::vector<FieldVal> fields;
379
380 fields.push_back( FieldVal( "notes", "1st update: set data_size to non-zero value" ) );
381 fields.push_back( FieldVal( "data_size", "883" ) );
382
383 Row row( fields );
384
385 std::string table( "metadata_v2r1" );
386
387 unsigned nChange = rdb->updateRows( table, row, whereSer );
388
389 // Now null out data_size
390 fields.clear();
391 fields.push_back( FieldVal( "data_size", "", true ) );
392 fields.push_back( FieldVal( "notes", "2nd update: data_size set to NULL" ) );
393 Row row2( fields );
394
395 nChange += rdb->updateRows( table, row2, whereSer );
396 return nChange;
397}
398
399void tryQuick( rdbModel::Table* t, const std::string& colname ) {
400 // rdbModel::Column* cQuick = t->getQuick(colname);
401 rdbModel::Column* col = t->getColumnByName( colname );
402
403 if ( !col )
404 {
405 std::cerr << colname << " not found by getQuick" << std::endl;
406 return;
407 }
408
409 std::string name = col->getName();
410 if ( colname.compare( name ) != 0 )
411 { std::cerr << "Instead of " << colname << ", getColumnByName found " << name << std::endl; }
412
413 else
414 { std::cout << "getColumnByName found correct column with name " << colname << std::endl; }
415}
416
417int doSupersedes( rdbModel::Rdb* rdb, int serial, int* newSerial ) {
418 using rdbModel::FieldVal;
419 using rdbModel::Row;
420
421 int retVal;
422 int nSuccess = 0;
423 Row row;
424
425 // First put something in row that doesn't belong there
426 row.addField( FieldVal( "data_ident", "supFile.xml" ) );
427 row.addField( FieldVal( "notes", "this supersede is not supposed to work" ) );
428 row.addField( FieldVal( "instrument", "cello" ) );
429
430 retVal = doSupersede( rdb, row, serial, newSerial );
431 if ( !retVal ) nSuccess++;
432
433 // Now leave out something necessary
434 row.clear();
435 row.addField( FieldVal( "notes", "oops! left out data_ident" ) );
436
437 retVal = doSupersede( rdb, row, serial, newSerial );
438 if ( !retVal ) nSuccess++;
439
440 // Now try to do it right!
441 row.clear();
442 row.addField( FieldVal( "data_ident", "supFile.xml" ) );
443 row.addField( FieldVal( "notes", "Try supersede with good row input" ) );
444 retVal = doSupersede( rdb, row, serial, newSerial );
445 if ( !retVal ) nSuccess++;
446
447 std::cout << "Attempted 3 supersedes; # success = " << nSuccess << std::endl;
448 return nSuccess;
449}
450
451int doSupersede( rdbModel::Rdb* rdb, rdbModel::Row& row, int serial, int* newSerial ) {
452
453 std::string table( "metadata_v2r1" );
454 int retVal = -1;
455
456 try
457 {
458 retVal = rdb->supersedeRow( table, row, serial, newSerial );
459 if ( retVal )
460 {
461 std::cout << "supersede of row " << serial << " failed with code " << retVal
462 << std::endl;
463 }
464 else { std::cout << "supsersede of row " << serial << " succeeded" << std::endl; }
465 } catch ( rdbModel::RdbException ex )
466 {
467 std::cout << "supersede of row " << serial << " failed with exception " << std::endl;
468 std::cout << ex.getMsg() << std::endl;
469 }
470 return retVal;
471}
bool getInterval(std::string &min, std::string &max)
Definition Datatype.cxx:154
void setBuilder(Builder *b)
Definition Manager.cxx:35
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 MATCH matchSchema(Rdb *rdb, bool matchDbName=true)
int supersedeRow(const std::string &tName, Row &row, int oldKey, int *newKey=0) const
Definition Rdb.cxx:87
Table * getTable(const std::string &name) const
Definition Rdb.cxx:18
int insertLatest(Table *t, Row &row, int *serial=0) const
Definition Rdb.cxx:72
int updateRows(const std::string &tName, Row &row, Assertion *where) const
Definition Rdb.cxx:61
Column * getColumn(const std::string &tableName, const std::string &colName) const
Definition Rdb.cxx:28
int insertRow(const std::string &tName, Row &row, int *serial=0) const
Definition Rdb.cxx:50
virtual unsigned int getNRows() const =0
Return number of rows in results.
int main()
Definition phokhara.cc:42
int t()
Definition t.c:1
int doInsert(rdbModel::Rdb *con)
int doSmartInsert(rdbModel::Rdb *rdb)
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 doUpdate(rdbModel::Rdb *, int serial)