71 #include "mysql_com.h"
73 #include "StMessMgr.h"
74 #include "StDbBroker.h"
76 extern "C" void * DbUse(uint *nRows,
78 const char * tableName,
79 const char * structName,
84 enum EColumnType {kNAN, kFloat, kInt, kLong, kShort, kDouble, kUInt
85 ,kULong, kUShort, kUChar, kChar };
98 unsigned int num_fields;
99 unsigned int num_rows;
103 std::ostringstream Query;
107 char currentDateTime[20];
110 sprintf(currentDateTime,
"%.8d",datetime[0]);
111 sprintf(time,
"%.6d",datetime[1]);
112 strcat(currentDateTime,time);
114 currentDateTime[19]=
'\0';
115 currentDateTime[18]=currentDateTime[13];
116 currentDateTime[17]=currentDateTime[12];
117 currentDateTime[16]=
':';
118 currentDateTime[15]=currentDateTime[11];
119 currentDateTime[14]=currentDateTime[10];
120 currentDateTime[13]=
':';
121 currentDateTime[12]=currentDateTime[9];
122 currentDateTime[11]=currentDateTime[8];
123 currentDateTime[10]=
' ';
124 currentDateTime[9]=currentDateTime[7];
125 currentDateTime[8]=currentDateTime[6];
126 currentDateTime[7]=
'-';
127 currentDateTime[6]=currentDateTime[5];
128 currentDateTime[5]=currentDateTime[4];
129 currentDateTime[4]=
'-';
143 char *dbName=
new char[strlen(
"params")+1]; strcpy(dbName,
"params");
145 char *dbHost=
new char[strlen(
"db1.star.bnl.gov")+1];strcpy(dbHost,
"db1.star.bnl.gov");
152 if (!mysql_real_connect(&mysql,dbHost,
"",
"",dbName,0,NULL,0))
154 LOG_ERROR <<
"Failed to connect to database: Error: "
155 << mysql_error(&mysql) << endm;
163 if(strlen(tableName)>0)
166 Query <<
"SELECT DISTINCT MAX(instances.validFrom) FROM instances, structures WHERE instances.strID=structures.ID AND instances.name=\"" << tableName <<
"\" AND structures.name=\"" << structName <<
"\" AND instances.validFrom<\""<<currentDateTime<<
"\" GROUP BY instances.name"<< std::ends;
171 LOG_ERROR<<
"ERROR: Zero length for Table Name is not allowed"<<endm;
179 if (mysql_real_query(&mysql, Query.str().c_str(), int(Query.tellp())-1))
181 LOG_ERROR <<
"Failed to query: Error: " << mysql_error(&mysql) << endm;
187 result = mysql_store_result(&mysql);
190 num_fields = mysql_num_fields(result);
191 if (num_fields!=1) LOG_ERROR <<
"ERROR: wrong size of LATEST query"<<endm;
193 num_latest = mysql_num_rows(result);
197 LOG_ERROR <<
"INFO: db " << dbName <<
" on host "<< dbHost
198 <<
" has no struct+table pair "<<structName<<
"+"<< tableName
199 <<
" valid for "<<currentDateTime <<endm;
205 if (num_latest>1) LOG_ERROR <<
"ERROR: found more than one latest date"
206 << tableName << endm;
209 row = mysql_fetch_row(result);
211 strncpy(validFrom,row[0],19);validFrom[19]=
'\0';
214 for(
int i3=0;i3<3;i3++,++ic) {
215 for(
int i2=0;i2<2;i2++,++ic) {
216 temps[ic]=row[0][ic];
220 latestDirTime = atoi(temps);
224 strncpy(temps,validFrom,10);
231 latestDirDate = atoi(temps);
233 mysql_free_result(result);
237 LOG_ERROR <<
"no result: Error: " << mysql_error(&mysql) << endm;
245 Query <<
"SELECT DISTINCT instances.ID, instances.nRows, instances.strID, structures.sizeOfStruct, structures.nElements FROM instances, structures WHERE instances.strID=structures.ID AND instances.name=\"" << tableName <<
"\" AND structures.name=\"" << structName <<
"\" AND instances.validFrom=\""<<validFrom<<
"\" ORDER BY instances.entered"<< std::ends;
249 uint num_instances=99999;
250 int latestDirID=99999;
251 int latestStrID=99999;
252 uint sizeOfDbStruct=99999;
255 if (mysql_real_query(&mysql, Query.str().c_str(), int(Query.tellp())-1))
257 LOG_ERROR <<
"Failed to query: Error: " << mysql_error(&mysql) << endm;
263 result = mysql_store_result(&mysql);
266 num_fields = mysql_num_fields(result);
267 if (num_fields!=5) LOG_ERROR <<
"ERROR: wrong size of latest entries query"<<endm;
269 num_instances = mysql_num_rows(result);
271 if (num_instances==0)
273 LOG_ERROR <<
"ERROR: db " << dbName <<
" has lost the struct+table pair "
274 <<structName<<
"+"<< tableName << endm;
282 LOG_ERROR <<
"INFO: db " << dbName <<
" has more then one struct+table pair "
283 <<structName<<
"+"<< tableName
284 <<
" valid for "<<currentDateTime
285 <<
", the LAST INSERTED is used"<<endl;
286 LOG_ERROR <<
"database query: " << Query.str() << endm;
288 for (uint
id=0;
id<num_instances;
id++)
290 row = mysql_fetch_row(result);
291 latestDirID = atoi(row[0]);
292 *nRows = (uint) atoi(row[1]);
293 latestStrID = atoi(row[2]);
294 sizeOfDbStruct = (uint)atoi(row[3]);
295 nDbVar = (uint)atoi(row[4]);
298 mysql_free_result(result);
302 LOG_ERROR <<
"no result: Error: " << mysql_error(&mysql) << endm;
310 if(sizeOfDbStruct!=sizeOfStruct)
312 LOG_ERROR<<
"ERROR: DB struct byteSize is "<<sizeOfDbStruct<<endm;
313 LOG_ERROR<<
" user struct byteSize is "<<sizeOfStruct<<endm;
314 LOG_ERROR <<
"structure: "<<structName<<endm;
321 LOG_ERROR <<
"ERROR: DB struct nVariables is "<<nDbVar<<endm;
322 LOG_ERROR <<
" user struct nVariables is "<<nVar<<endm;
323 LOG_ERROR <<
"structure: "<<structName<<endm;
337 Query<<
"SELECT name, type, offset, nDims, firstDim FROM headers WHERE strID="
338 << latestStrID <<
" ORDER BY offset" << std::ends;
341 if (mysql_real_query(&mysql, Query.str().c_str(), int(Query.tellp())-1))
343 LOG_ERROR <<
"Failed to query: Error: " << mysql_error(&mysql) << endm;
349 result = mysql_store_result(&mysql);
352 num_fields = mysql_num_fields(result);
353 if (num_fields!=5) LOG_ERROR<<
"ERROR: wrong size of headers query"<<endm;
355 num_rows = mysql_num_rows(result);
360 cout<<
"WARNING: database structure is of "<< num_rows
361 <<
" variables, this structure is "<< nVar <<endl;
364 types =
new char*[num_rows];
365 names =
new char*[num_rows];
366 offset =
new int[num_rows];
367 nDims =
new int[num_rows];
368 firstDim =
new int[num_rows];
370 for (j=0;j<num_rows;j++)
372 row = mysql_fetch_row(result);
374 names[j] = strdup(row[0]);
375 types[j] = strdup(row[1]);
376 offset[j] = atoi(row[2]);
377 nDims[j] = atoi(row[3]);
378 firstDim[j] = atoi(row[4]);
386 mysql_free_result(result);
397 if (strcmp(d[j].fColumnName,names[j]))
401 if ( d[j].fOffset!=(
unsigned int)offset[j] )
406 if ( d[j].fDimensions!=(
unsigned int)nDims[j] )
411 if ( d[j].fIndexArray[0]!=(
unsigned int)firstDim[j] )
420 LOG_ERROR<<
"structure " << structName
421 <<
" is not compatible with database instance ID "<<latestDirID<<endm;
422 LOG_ERROR <<
"nVar "<<nVar<<
", count "<<count<<endm;
426 LOG_ERROR<<
"names: \""<<d[j].fColumnName<<
"\" \""<<names[j]<<
"\""<<endm;
427 if (strcmp(d[j].fColumnName,names[j]))
430 LOG_ERROR<<
"offset: "<<d[j].fOffset<<
" "<<offset[j]<<endm;
431 if ( d[j].fOffset!=(
unsigned int)offset[j] )
434 LOG_ERROR<<
"nDims: "<<d[j].fDimensions<<
" "<<nDims[j]<<endm;
435 if ( d[j].fDimensions!=(
unsigned int)nDims[j] )
438 LOG_ERROR<<
"firstDim: "<<d[j].fIndexArray[0]<<
" "<<firstDim[j]<<endm;
439 if ( d[j].fIndexArray[0]!=(
unsigned int)firstDim[j] )
457 void* pDbData = calloc((
size_t) *nRows, (
size_t) sizeOfDbStruct);
460 LOG_ERROR<<
"DbUse: failed to allocate memory nedeed for the array of "
461 << *nRows <<
" structs " <<structName <<
" each of "
462 <<sizeOfStruct <<
" bytes"<<endm;
473 char* pCurrent = (
char*) pDbData;
476 unsigned long *lengths;
479 Query <<
"SELECT bytes FROM bytes WHERE instanceID="<<latestDirID<< std::ends;
483 if (mysql_real_query(&mysql, Query.str().c_str(), int(Query.tellp())-1))
485 LOG_ERROR <<
"Failed to query: Error: " << mysql_error(&mysql) << endm;
486 LOG_ERROR <<
"database query: " << Query.str() << endm;
492 result = mysql_store_result(&mysql);
495 LOG_ERROR <<
"no result: Error: " << mysql_error(&mysql) << endm;
509 num_fields = mysql_num_fields(result);
510 if (num_fields!=1) LOG_ERROR <<
"ERROR: wrong size of blob query"<<endm;
512 num_blobs = mysql_num_rows(result);
516 LOG_ERROR <<
"ERROR: db " << dbName <<
" has lost BLOB for struct+table pair "
517 <<structName<<
"+"<< tableName
518 <<
" valid for "<<currentDateTime <<endm;
531 if (num_blobs>1) LOG_ERROR <<
"ERROR: found more than one BLOB for "
534 row = mysql_fetch_row(result);
538 lengths = mysql_fetch_lengths(result);
541 if (lengths[0]!=(*nRows)*sizeOfDbStruct)
543 LOG_ERROR <<
"ERROR: wrong blob size "
545 LOG_ERROR <<
"lengths[0] "<<lengths[0]
546 <<
", nRows "<<(*nRows)
547 <<
", sizeOfDbStruct "<<sizeOfDbStruct
548 <<
", nRows*sizeOfDbStruct "<<(*nRows)*sizeOfDbStruct
563 memcpy(pCurrent,row[0],(
size_t) (*nRows)*sizeOfDbStruct);
564 #else // do byte swapping
566 uint i, k, nTimes, firstByte, firstDbByte;
569 for (i=0;i<*nRows;i++)
574 switch(d[j].fDimensions)
580 nTimes=d[j].fIndexArray[0];
583 LOG_ERROR<<
"two-dims not handled yet"<<endm;
588 LOG_ERROR <<
"ERROR: more that one dimension "<<endm;
594 firstByte=i*sizeOfStruct+d[j].fOffset;
595 firstDbByte=i*sizeOfDbStruct+offset[j];
597 for (k=0;k<nTimes;k++) {
600 switch((StDbBroker::EColumnType)d[j].fType)
604 pCurrent[firstByte+k]=row[0][firstDbByte+k];
609 pCurrent[firstByte+2*k+1]=row[0][+2*k ];
610 pCurrent[firstByte+2*k ]=row[0][firstDbByte+2*k+1];
621 pCurrent[firstByte+4*k+3]=row[0][firstDbByte+4*k ];
622 pCurrent[firstByte+4*k+2]=row[0][firstDbByte+4*k+1];
623 pCurrent[firstByte+4*k+1]=row[0][firstDbByte+4*k+2];
624 pCurrent[firstByte+4*k ]=row[0][firstDbByte+4*k+3];
629 pCurrent[firstByte+8*k+7]=row[0][firstDbByte+8*k ];
630 pCurrent[firstByte+8*k+6]=row[0][firstDbByte+8*k+1];
631 pCurrent[firstByte+8*k+5]=row[0][firstDbByte+8*k+2];
632 pCurrent[firstByte+8*k+4]=row[0][firstDbByte+8*k+3];
633 pCurrent[firstByte+8*k+3]=row[0][firstDbByte+8*k+4];
634 pCurrent[firstByte+8*k+2]=row[0][firstDbByte+8*k+5];
635 pCurrent[firstByte+8*k+1]=row[0][firstDbByte+8*k+6];
636 pCurrent[firstByte+8*k ]=row[0][firstDbByte+8*k+7];
641 LOG_ERROR <<
"ERROR: unknown type!"<<endm;
650 mysql_free_result(result);
657 Query <<
"SELECT DISTINCT MIN(instances.validFrom) FROM instances, structures WHERE instances.strID=structures.ID AND instances.name=\"" << tableName <<
"\" AND structures.name=\"" << structName <<
"\" AND instances.validFrom>\""<<currentDateTime<<
"\" GROUP BY instances.name"<<std::ends;
665 if (mysql_real_query(&mysql, Query.str().c_str(), int(Query.tellp())-1))
667 LOG_ERROR <<
"Failed to query: Error: " << mysql_error(&mysql) << endm;
673 result = mysql_store_result(&mysql);
676 num_fields = mysql_num_fields(result);
677 if (num_fields!=1) LOG_ERROR <<
"ERROR: wrong size of next date query"<<endm;
679 num_next = mysql_num_rows(result);
686 nextDirDate=20380101;
691 if (num_next>1) LOG_ERROR <<
"ERROR: found more than one next date"
695 row = mysql_fetch_row(result);
699 strncpy(validFrom,row[0],19);validFrom[19]=
'\0';
702 for(
int i3=0;i3<3;i3++,++ic) {
703 for(
int i2=0;i2<2;i2++,++ic) {
704 temps[ic]=row[0][ic];
708 nextDirTime = atoi(temps);
711 strncpy(temps,validFrom,10);
718 nextDirDate = atoi(temps);
720 mysql_free_result(result);
724 LOG_ERROR <<
"no result: Error: " << mysql_error(&mysql) << endm;
749 datetime[0] = latestDirDate;
750 datetime[1] = latestDirTime;
751 datetime[2] = nextDirDate;
752 datetime[3] = nextDirTime;