00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 #include "MysqlDb.h"
00239 #include "StDbManager.hh"
00240 #include "stdb_streams.h"
00241 #include "StDbDefaults.hh"
00242 #include "StDbManagerImpl.hh"
00243
00244 #include <unistd.h>
00245 #include <sys/types.h>
00246 #include <pwd.h>
00247 #include <string>
00248
00249 #include <cassert>
00250 #include <ctime>
00251
00252 #ifndef __STDB_STANDALONE__
00253 #include "StMessMgr.h"
00254 #else
00255 #define LOG_DEBUG cout
00256 #define LOG_INFO cout
00257 #define LOG_WARN cout
00258 #define LOG_ERROR cerr
00259 #define LOG_FATAL cerr
00260 #define LOG_QA cout
00261 #define endm "\n"
00262 #endif
00263
00264
00265
00266 #ifdef HPUX
00267 #define freeze(i) str()
00268 #endif
00269
00270
00271 #define CR_MIN_ERROR 2000
00272 #define CR_MAX_ERROR 2999
00273 #define CR_UNKNOWN_ERROR 2000
00274 #define CR_SOCKET_CREATE_ERROR 2001
00275 #define CR_CONNECTION_ERROR 2002
00276 #define CR_CONN_HOST_ERROR 2003
00277 #define CR_IPSOCK_ERROR 2004
00278 #define CR_UNKNOWN_HOST 2005
00279 #define CR_SERVER_GONE_ERROR 2006
00280 #define CR_VERSION_ERROR 2007
00281 #define CR_OUT_OF_MEMORY 2008
00282 #define CR_WRONG_HOST_INFO 2009
00283 #define CR_LOCALHOST_CONNECTION 2010
00284 #define CR_TCP_CONNECTION 2011
00285 #define CR_SERVER_HANDSHAKE_ERR 2012
00286 #define CR_SERVER_LOST 2013
00287 #define CR_COMMANDS_OUT_OF_SYNC 2014
00288 #define CR_NAMEDPIPE_CONNECTION 2015
00289 #define CR_NAMEDPIPEWAIT_ERROR 2016
00290 #define CR_NAMEDPIPEOPEN_ERROR 2017
00291 #define CR_NAMEDPIPESETSTATE_ERROR 2018
00292
00293 #define __CLASS__ "MysqlDb"
00294
00295 namespace {
00296
00297 time_t get_time_nanosec() {
00298 timespec ts;
00299 clock_gettime(CLOCK_MONOTONIC, &ts);
00300 return (ts.tv_sec*1000 + ts.tv_nsec/1000000);
00301 }
00302
00303 }
00304
00305 static const char* binaryMessage = {"Cannot Print Query with Binary data"};
00306
00307
00308
00309
00311
00312 MysqlDb::MysqlDb(): mdbhost(0), mdbName(NULL), mdbuser(0), mdbpw(0), mdbPort(0),mdbServerVersion(0),mlogTime(false) {
00313
00314 mhasConnected=false;
00315 mhasBinaryQuery=false;
00316 mtimeout=1;
00317 mQuery=0;
00318 mQueryLast=0;
00319 mRes= new MysqlResult;
00320 for(int i=0;i<200;i++)cnames[i]=0;
00321
00322 mSysusername = "N/A";
00323 struct passwd *pwd = 0;
00324 pwd = getpwuid(geteuid());
00325 if (pwd) {
00326 mSysusername = pwd->pw_name;
00327 }
00328 }
00330
00331 MysqlDb::~MysqlDb(){
00332 if(mQuery) delete [] mQuery;
00333 if(mQueryLast) delete [] mQueryLast;
00334 Release();
00335 if(mRes) delete mRes;
00336 if(mhasConnected)mysql_close(&mData);
00337 if(mdbhost) delete [] mdbhost;
00338 if(mdbuser) delete [] mdbuser;
00339 if(mdbpw) delete [] mdbpw;
00340 if(mdbName) delete [] mdbName;
00341 if(mdbServerVersion) delete [] mdbServerVersion;
00342
00343 #ifdef MYSQL_VERSION_ID
00344 # if MYSQL_VERSION_ID > 50044
00345 mysql_library_end();
00346 # endif
00347 #endif
00348
00349 }
00351 bool MysqlDb::reConnect(){
00352 #define __METHOD__ "reConnect()"
00353
00354 bool connected=false;
00355 unsigned int timeOutConnect=mtimeout;
00356 my_bool auto_reconnect = 1;
00357
00358 while(!connected && timeOutConnect<600){
00359 mysql_options(&mData,MYSQL_OPT_CONNECT_TIMEOUT,(const char*)&timeOutConnect);
00360
00361 #ifdef MYSQL_VERSION_ID
00362 # if MYSQL_VERSION_ID > 50044
00363 mysql_options(&mData,MYSQL_OPT_RECONNECT, &auto_reconnect);
00364 # endif
00365 #endif
00366
00367 loadBalance();
00368
00369
00370
00371 mysql_ssl_set(&mData, NULL, NULL, NULL, NULL, "AES128-SHA");
00372
00373 unsigned long client_flag = CLIENT_COMPRESS;
00374
00375 if(mysql_real_connect(&mData,mdbhost,mdbuser,mdbpw,mdbName,mdbPort,NULL,client_flag)) {
00376 connected=true;
00377 std::string query = "SHOW STATUS LIKE 'Ssl_cipher'";
00378 mysql_query(&mData, query.c_str());
00379 MYSQL_RES *result = 0;
00380 MYSQL_ROW row = 0;
00381 int num_fields = 0;
00382 result = mysql_store_result(&mData);
00383 num_fields = mysql_num_fields(result);
00384 if (num_fields >= 2) {
00385 row = mysql_fetch_row(result);
00386 if (row && row[0] && row[1]) {
00387 LOG_INFO << row[0] << " = " << row[1] << endm;
00388 }
00389 }
00390 mysql_free_result(result);
00391 }
00392
00393 if(!connected){
00394 timeOutConnect*=2;
00395 StString wm;
00396 wm << " Cannot connect to " << mdbhost << ":" << mdbPort << ", database server is busy or unreachable.\n";
00397 wm << " Returned error =";
00398 wm << mysql_error(&mData)<<".\n Will re-try with timeout set at \n==> ";
00399 wm << timeOutConnect<<" seconds <==";
00400 StDbManager::Instance()->printInfo((wm.str()).c_str(),dbMConnect,__LINE__,__CLASS__,__METHOD__);
00401 }
00402 }
00403
00404 if(connected){
00405 if(mdbServerVersion) delete [] mdbServerVersion;
00406
00407 if(!mData.server_version){
00408 StString smm;
00409 smm<<" No Server version - most likely incompatible libraries \n CONTACT DATABASE ADMINISTRATOR";
00410 StDbManager::Instance()->printInfo((smm.str()).c_str(),dbMConnect,__LINE__,__CLASS__,__METHOD__);
00411 assert(mData.server_version);
00412 }
00413
00414
00415 mdbServerVersion=new char[strlen(mData.server_version)+1];
00416 strcpy(mdbServerVersion,mData.server_version);
00417 }
00418
00419 return connected;
00420
00421 #undef __METHOD__
00422 }
00423
00425 bool MysqlDb::Connect(const char *aHost, const char *aUser, const char *aPasswd, const char *aDb, const int aPort){
00426 #define __METHOD__ "Connect(host,user,pw,database,port)"
00427
00428 m_Mgr.init();
00429
00430 if(aUser){
00431 if(mdbuser) delete [] mdbuser;
00432 mdbuser = new char[strlen(aUser)+1]; strcpy(mdbuser,aUser);
00433 }
00434 if(aPasswd){
00435 if(mdbpw) delete [] mdbpw;
00436 mdbpw = new char[strlen(aPasswd)+1]; strcpy(mdbpw,aPasswd);
00437 }
00438 mdbPort = aPort;
00439
00440
00441
00442 #ifndef NoXmlTreeReader
00443 if (!my_manager->myServiceBroker)
00444 #endif
00445 {
00446
00447 if(mdbhost) delete [] mdbhost;
00448 mdbhost = new char[strlen(aHost)+1];
00449 strcpy(mdbhost,aHost);
00450 }
00451
00452
00453 if(mdbName) {
00454 delete [] mdbName;
00455 mdbName=NULL;
00456 }
00457 if(aDb && (strcmp(aDb," ")!=0)){
00458 mdbName = new char[strlen(aDb)+1];
00459 strcpy(mdbName,aDb);
00460 }
00461
00462 bool tRetVal = false;
00463 double t0=mqueryLog.wallTime();
00464 if(mlogTime)mconnectLog.start();
00465 if (!mysql_init(&mData))
00466 return (bool) StDbManager::Instance()->printInfo("Mysql Init Error=",mysql_error(&mData),dbMErr,__LINE__,__CLASS__,__METHOD__);
00467
00468
00469 StString cs;
00470 if(reConnect()){
00471
00472 t0=mqueryLog.wallTime()-t0;
00473 cs<< "Server Connecting:"; if(mdbName)cs<<" DB=" << mdbName ;
00474 cs<< " Host=" << mdbhost <<":"<<mdbPort <<stendl;
00475 cs<< " --> Connection Time="<<t0<<" sec ";
00476 if(mdbServerVersion)cs<<" MysqlVersion="<<mdbServerVersion;
00477
00478 StDbManager::Instance()->printInfo((cs.str()).c_str(),dbMConnect,__LINE__,__CLASS__,__METHOD__);
00479 tRetVal=true;
00480 } else {
00481 cs << "Making Connection to DataBase = " << aDb;
00482 cs << " On Host = " << mdbhost <<":"<<mdbPort;
00483 cs << " MySQL returned error " << mysql_error(&mData);
00484 StDbManager::Instance()->printInfo((cs.str()).c_str(),dbMConnect,__LINE__,__CLASS__,__METHOD__);
00485 }
00486
00487 if(mlogTime)mconnectLog.end();
00488 mhasConnected = tRetVal;
00489 return tRetVal;
00490 #undef __METHOD__
00491 }
00492
00494
00495 bool MysqlDb::loadBalance()
00496 {
00497 bool ok = false;
00498
00499 #ifndef NoXmlTreeReader
00500 time_t startTime = get_time_nanosec();
00501 time_t stopTime = 0, totalTime = 0;
00502
00503 if (my_manager->myServiceBroker)
00504 {
00505 my_manager->myServiceBroker->DoLoadBalancing();
00506 short mSBStatus = my_manager->myServiceBroker->GetStatus();
00507 if (mSBStatus==st_db_service_broker::NO_ERROR)
00508 {
00509
00510 const char* lbHostName = (my_manager->myServiceBroker->GiveHostName()).c_str();
00511 if(mdbhost) delete [] mdbhost;
00512 mdbhost = new char[strlen(lbHostName)+1];
00513 strcpy(mdbhost,lbHostName);
00514 ok = true;
00515 mdbPort = my_manager->myServiceBroker->GiveHostPort();
00516 }
00517 else
00518 {
00519 LOG_ERROR << "MysqlDb::Connect: StDbServiceBroker error "<<mSBStatus<<endm;
00520 }
00521 }
00522
00523 stopTime = get_time_nanosec();
00524 totalTime = stopTime - startTime;
00525 LOG_INFO << "MysqlDb::Connect: Load balancer took "<< totalTime <<" ms, will use "<< mdbhost << ":" << mdbPort << endm;
00526
00527 #endif
00528
00529 return ok;
00530 }
00532
00533
00534
00535 char* MysqlDb::printQuery(){ return mQueryLast; };
00536
00538 void MysqlDb::RazQuery() {
00539
00540 if (mQueryLast){
00541 delete [] mQueryLast;
00542 mQueryLast=0;
00543 }
00544 if(mhasBinaryQuery){
00545 mQueryLast = new char[strlen(binaryMessage)+1];
00546 strcpy(mQueryLast,binaryMessage);
00547 if(mQuery)delete [] mQuery;
00548 } else {
00549 if(mQuery){
00550 mQueryLast=new char[strlen(mQuery)+1];
00551 strcpy(mQueryLast,mQuery);
00552 delete [] mQuery;
00553 }
00554 }
00555
00556 mQuery = 0;
00557 mQueryLen=0;
00558
00559
00560 mhasBinaryQuery=false;
00561 }
00562
00563 bool MysqlDb::checkForTable(const char* tableName){
00564
00565 mRes->Release();
00566 mRes->mRes=mysql_list_tables(&mData,tableName);
00567 if(mRes->mRes==NULL) return false;
00568 mRes->Release();
00569
00570 return true;
00571 };
00572
00574
00575 bool MysqlDb::ExecQuery(){
00576 #define __METHOD__ "ExecQuery()"
00577
00578
00579 std::string mQ(mQuery,mQueryLen);
00580 mQ.append(" /* RUSR: ");
00581 mQ.append(mSysusername);
00582 mQ.append(" | SUSR: ");
00583 if (mdbuser) {
00584 mQ.append(mdbuser);
00585 } else {
00586 mQ.append("N/A");
00587 }
00588 mQ.append(" */");
00589
00590 mqueryState=false;
00591
00592 size_t cache_length = 0;
00593 if (m_Mgr.isActive()) {
00594 std::string dbName = mdbName ? mdbName : "";
00595 const char* res = m_Mgr.get(dbName, mQuery, cache_length);
00596 if (res && cache_length) {
00597 return mqueryState = true;
00598 }
00599 }
00600
00601 if(mlogTime)mqueryLog.start();
00602
00603
00604
00605 int status=mysql_real_query(&mData,mQ.c_str(), mQ.size());
00606
00607 if( (status!=0) && ( mysql_errno(&mData)==CR_SERVER_GONE_ERROR || mysql_errno(&mData)==CR_SERVER_LOST ) ){
00608 StDbManager::Instance()->printInfo(mysql_error(&mData)," Lost server, will try to reconnect",dbMDebug,__LINE__,__CLASS__,__METHOD__);
00609 if(reConnect())status=mysql_real_query(&mData,mQuery,mQueryLen);
00610 }
00611
00612 if(status!=0)
00613 return StDbManager::Instance()->printInfo(" Query Failed ",mysql_error(&mData),dbMErr,__LINE__,__CLASS__,__METHOD__);
00614
00615 if(mlogTime)mqueryLog.end();
00616 mRes->Release();
00617
00618 if(mlogTime)msocketLog.start();
00619 mRes->mRes=mysql_store_result(&mData);
00620 if(mlogTime)msocketLog.end();
00621
00622 return mqueryState=true;
00623 }
00624
00626
00627 MysqlDb &MysqlDb::operator<<( const char *aQuery){
00628
00629 if (strcmp(aQuery,";")==0){
00630 ExecQuery();
00631 RazQuery();
00632 } else {
00633
00634 if(!mQuery){
00635 mQueryLen=strlen(aQuery);
00636 mQuery = new char[mQueryLen+1];
00637 strcpy(mQuery,aQuery);
00638 } else {
00639 char* tQuery = new char[strlen(mQuery)+1];
00640 strcpy(tQuery,mQuery);
00641 delete [] mQuery;
00642 mQuery = new char[mQueryLen+strlen(aQuery)+1];
00643 memcpy(mQuery,tQuery,mQueryLen);
00644 strcpy(&mQuery[mQueryLen],aQuery);
00645 delete [] tQuery;
00646 mQueryLen=mQueryLen+strlen(aQuery);
00647 }
00648
00649 }
00650
00651 return *this;
00652 }
00653
00655
00656 MysqlDb &MysqlDb::operator<<( const MysqlBin *aBin ){
00657
00658 mhasBinaryQuery=true;
00659
00660 char *tQuery = new char[mQueryLen+aBin->mLen+1];
00661 memcpy(tQuery,mQuery,mQueryLen);
00662 memcpy(&tQuery[mQueryLen],aBin->mBinData,aBin->mLen+1);
00663
00664 if(mQuery)delete [] mQuery;
00665 mQuery=tQuery;
00666 mQueryLen=mQueryLen+aBin->mLen;
00667
00668 return *this;
00669 };
00670
00672
00673 bool MysqlDb::InputStart(const char* table,StDbBuffer *aBuff, const char* colList, int nRows,bool& hasBinary){
00674
00675 bool tRetVal=false;
00676 if(!table || !aBuff || !colList) return tRetVal;
00677
00678 bool change=aBuff->IsClientMode();
00679 if(change) aBuff->SetStorageMode();
00680
00681 *this << "select * from " << table << " where null"<< endsql;
00682 *this << "insert delayed into " << table << " ("<<colList<<") VALUES(";
00683 int i;
00684
00685 char* tmpString=new char[strlen(colList)+1];
00686 strcpy(tmpString,colList);
00687 char *ptr1,*ptr2;
00688 jfields=0;
00689 bool done = false;
00690 ptr1=tmpString;
00691
00692 while(!done){
00693 if((ptr2=strstr(ptr1,","))){
00694 *ptr2='\0';
00695 } else {
00696 done=true;
00697 }
00698 if(*ptr1==' ')ptr1++;
00699 if(cnames[jfields]) delete [] cnames[jfields];
00700 cnames[jfields]=new char[strlen(ptr1)+1];
00701 strcpy(cnames[jfields],ptr1);
00702 if(!done){
00703 ptr1=ptr2+1;
00704 *ptr2=',';
00705 }
00706 jfields++;
00707 }
00708 delete [] tmpString;
00709 int nfields=NbFields();
00710 int fcount=0;
00711 hasBinary=false;
00712
00713 for(int k=0;k<jfields;k++){
00714 for(i=0;i<nfields;i++)
00715 if(strcmp(mRes->mRes->fields[i].name,cnames[k])==0)break;
00716
00717 if(i==nfields)continue;
00718 fcount++;
00719 isBlob[k]=( (IS_BLOB(mRes->mRes->fields[i].flags)) ||
00720 (mRes->mRes->fields[i].type ==254) );
00721 isBinary[k]= (mRes->mRes->fields[i].flags&BINARY_FLAG);
00722 isSpecialType[k]=(mRes->mRes->fields[i].type ==254);
00723
00724 if(isBinary[k])hasBinary=true;
00725 }
00726 if(fcount!=jfields) done=false;
00727
00728 return done;
00729
00730 };
00731
00732 bool MysqlDb::InputRow(StDbBuffer* aBuff, int row){
00733
00734 char* tVal;tVal=0;
00735 int len;
00736 aBuff->SetStorageMode();
00737 if(row>0)*this<<"),(";
00738 int k;
00739 for(k=0;k<jfields;k++){
00740 if(k!=0)*this<<",";
00741 if(isBlob[k]){
00742 if(isBinary[k]){
00743 if(!aBuff->ReadArray(tVal,len,cnames[k]))break;
00744 *this<<"'"<<Binary(len,(float*)tVal)<<"'";
00745 } else if(isSpecialType[k]) {
00746 if(!aBuff->ReadScalar(tVal,cnames[k]))break;
00747 *this<<"'"<<tVal<<"'";
00748 } else {
00749 char** tVal2=0;
00750 if(!aBuff->ReadArray(tVal2,len,cnames[k]))break;
00751 tVal=CodeStrArray(tVal2,len);
00752 for(int jj=0;jj<len;jj++)if(tVal2[jj])delete []tVal2[jj];
00753 *this<<"'"<<tVal<<"'";
00754 }
00755 } else {
00756 if(!aBuff->ReadScalar(tVal,cnames[k])) break;
00757 *this<<"'"<<tVal<<"'";
00758 }
00759 }
00760
00761 aBuff->SetClientMode();
00762
00763 if(k!=jfields){
00764 RazQuery();
00765 return false;
00766 }
00767
00768 return true;
00769 }
00770
00771 bool MysqlDb::InputEnd(){
00772
00773 bool tRetVal=false;
00774 *this<<")"<<endsql;
00775 if(mqueryState)tRetVal=true;
00776 return tRetVal;
00777
00778 };
00780
00781 bool MysqlDb::Input(const char *table,StDbBuffer *aBuff){
00782 bool tRetVal=false;
00783 bool change=aBuff->IsClientMode();
00784 if (change) aBuff->SetStorageMode();
00785 aBuff->SetStorageMode();
00786 if (aBuff) {
00787 *this << "select * from " << table << " where null"<< endsql;
00788 *this << "insert into " << table << " set ";
00789 bool tFirst=true;
00790 char* tVal;tVal=0;
00791 int len;
00792 unsigned i;
00793
00794 for (i=0;i<NbFields();i++) {
00795 if ((IS_BLOB(mRes->mRes->fields[i].flags) ) ||
00796 mRes->mRes->fields[i].type ==254) {
00797 if (mRes->mRes->fields[i].flags&BINARY_FLAG) {
00798 if (aBuff->ReadArray(tVal,len,mRes->mRes->fields[i].name)){
00799 if (tFirst) {
00800 tFirst=false;
00801 } else {
00802 *this << ",";
00803 };
00804 *this << mRes->mRes->fields[i].name << "='" << Binary(len,(float*)tVal)<<"'";
00805 };
00806 }else{
00807 if(mRes->mRes->fields[i].type==254){
00808 if (aBuff->ReadScalar(tVal,mRes->mRes->fields[i].name)) {
00809 if (tFirst) {
00810 tFirst=false;
00811 } else {
00812 *this << ",";
00813 };
00814 *this << mRes->mRes->fields[i].name << "='" << tVal << "'";
00815 };
00816 } else {
00817 char** tVal2=0;
00818 if (aBuff->ReadArray(tVal2,len,mRes->mRes->fields[i].name)){
00819 tVal=CodeStrArray(tVal2,len);
00820 int j;for (j=0;j<len;j++) {if (tVal2[j]) delete [] tVal2[j];};
00821 delete [] tVal2;
00822 if (tFirst) {
00823 tFirst=false;
00824 } else {
00825 *this << ",";
00826 };
00827 *this << mRes->mRes->fields[i].name << "='" << tVal<<"'";
00828 }
00829 };
00830 };
00831 } else {
00832 if (aBuff->ReadScalar(tVal,mRes->mRes->fields[i].name)) {
00833 if (tFirst) {
00834 tFirst=false;
00835 } else {
00836 *this << ",";
00837 };
00838 *this << mRes->mRes->fields[i].name << "='" << tVal << "'";
00839 };
00840 };
00841 if (tVal) delete [] tVal;tVal=0;
00842 };
00843 if (tFirst) {
00844 RazQuery();
00845 } else {
00846 *this << endsql;
00847 if(mqueryState)tRetVal=true;
00848 };
00849 };
00850
00851 if (change) aBuff->SetClientMode();
00852 aBuff->SetClientMode();
00853 return tRetVal;
00854 };
00855
00857
00858 bool MysqlDb::Output(StDbBuffer *aBuff){
00859
00860
00861
00862 if (m_Mgr.isValueFound()) {
00863
00864
00865 return m_Mgr.processOutput(aBuff);
00866 } else if (!m_Mgr.isValueFound() && mRes->mRes) {
00867 if (!m_Mgr.getLastGroupKey().empty() && !m_Mgr.getLastKey().empty() && m_Mgr.getLastGroupKey() != " " && m_Mgr.getLastKey() != " ") {
00868
00869
00870 aBuff->SetStorageMode();
00871 m_Mgr.set(m_Mgr.getLastGroupKey().c_str(), m_Mgr.getLastKey().c_str(), mRes->mRes, 0);
00872 mysql_data_seek(mRes->mRes, 0);
00873 aBuff->SetClientMode();
00874 }
00875 }
00876
00877
00878 if(mlogTime)msocketLog.start();
00879 MYSQL_ROW tRow=mysql_fetch_row(mRes->mRes);
00880 if(!tRow) return false;
00881 unsigned long * lengths=mysql_fetch_lengths(mRes->mRes);
00882 unsigned tNbFields=NbFields();
00883 if(mlogTime)msocketLog.end();
00884 int i;
00885 bool tRetVal=false;
00886 bool change=aBuff->IsClientMode();
00887 if (change) aBuff->SetStorageMode();
00888 aBuff->SetStorageMode();
00889
00890 for (i=0;i<(int)tNbFields;i++){
00891 if(tRow[i]){
00892
00893
00894 if (IS_BLOB(mRes->mRes->fields[i].flags)) {
00895 if (mRes->mRes->fields[i].flags&BINARY_FLAG) {
00896 aBuff->WriteArray((char*)tRow[i],lengths[i],mRes->mRes->fields[i].name);
00897 }else {
00898 char** tStrPtr;
00899 int len;
00900 tStrPtr=DecodeStrArray((char*)tRow[i],len);
00901 aBuff->WriteArray(tStrPtr,len,mRes->mRes->fields[i].name);
00902 for(int k=0;k<len;k++)delete [] tStrPtr[k];
00903 delete [] tStrPtr;
00904
00905
00906
00907
00908
00909
00910
00911 StString cn;
00912 cn<<mRes->mRes->fields[i].name<<".text";
00913 aBuff->WriteScalar((char*)tRow[i],(cn.str()).c_str());
00914 };
00915 } else {
00916 aBuff->WriteScalar((char*)tRow[i],mRes->mRes->fields[i].name);
00917 };
00918 }
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930 tRetVal=true;
00931 };
00932 if (change) aBuff->SetClientMode();
00933 aBuff->SetClientMode();
00934 return tRetVal;
00935 }
00936
00938
00939 char** MysqlDb::DecodeStrArray(char* strinput , int &aLen){
00940
00941 if(!strinput){
00942
00943 char** tmparr = new char*[1];
00944 aLen = 1;
00945 *tmparr = new char[2];
00946 strcpy(*tmparr,"0");
00947 return tmparr;
00948 }
00949
00950 char* tPnt=strinput;
00951 aLen=0;
00952
00953 while (tPnt&&aLen<1024) {
00954 tPnt=strpbrk( tPnt,"\\,");
00955 if (tPnt!=0){
00956 if (*tPnt==',') {
00957 aLen++;tPnt++;
00958 } else {
00959 tPnt++;tPnt++;};
00960 };
00961 };
00962 aLen++;
00963 char** strarr=new char*[aLen];
00964 tPnt=strinput;
00965 char* tPntNew=tPnt;
00966 char *tBuff=new char[strlen(strinput)+1];
00967 char *tBuffInd=tBuff;
00968 int tCount=0;
00969 while (tPntNew) {
00970 tPntNew=strpbrk( tPnt,"\\,");
00971 if ((tPntNew==0)||*tPntNew==',') {
00972 if (tPntNew==0) {
00973 strcpy(tBuffInd,tPnt);
00974
00975 } else {
00976 strncpy(tBuffInd,tPnt,tPntNew-tPnt);
00977 *(tBuffInd+(tPntNew-tPnt))='\0';
00978 }
00979 strarr[tCount]=new char[strlen(tBuff)+1];
00980 strcpy(strarr[tCount],tBuff);
00981 tBuffInd=tBuff;
00982 tPnt=tPntNew+1;
00983 tCount++;
00984 } else {
00985 strncpy(tBuffInd,tPnt,tPntNew-tPnt);
00986 tBuffInd=tBuffInd+(tPntNew-tPnt);
00987 tPntNew++;
00988 if(*tPntNew=='\\'||*tPntNew==',') {
00989 *tBuffInd=*tPntNew;
00990 tBuffInd++;
00991 };
00992 *(tBuffInd)='\0';
00993 tPnt=tPntNew+1;
00994 };
00995 };
00996 delete [] tBuff;
00997 return strarr;
00998 }
00999
01001
01002 char* MysqlDb::CodeStrArray(char** strarr , int aLen){
01003 int tMaxLen=0;
01004 int i;
01005 for (i=0;i<aLen;i++) {
01006 if (strarr[i]) tMaxLen=tMaxLen+strlen(strarr[i])*2;
01007 tMaxLen++;
01008 };
01009 char* tTempVal=new char[tMaxLen+1];
01010 char* tRead;
01011 char* tWrite=tTempVal;
01012 for (i=0;i<aLen;i++) {
01013 if (strarr[i]){
01014 int j;
01015 tRead=strarr[i];
01016 for (j=0;j<(int)strlen(strarr[i]);j++) {
01017 if (*tRead=='\\'||*tRead==',') {
01018 *tWrite='\\';
01019 tWrite++;
01020 };
01021 *tWrite=*tRead;
01022 tWrite++;
01023 tRead++;
01024 };
01025 };
01026 *tWrite=',';
01027 tWrite++;
01028 };
01029 tWrite--;
01030 *tWrite='\0';
01031 char *tRetVal=new char[strlen(tTempVal)+1];
01032 strcpy(tRetVal,tTempVal);
01033 if (tTempVal) delete [] tTempVal;
01034 return tRetVal;
01035 };
01036
01038
01039 bool
01040 MysqlDb::setDefaultDb(const char* dbName){
01041
01042 if(!dbName || strlen(dbName)==0)return false;
01043 if(mdbName) delete [] mdbName;
01044 mdbName=new char[strlen(dbName)+1];
01045 strcpy(mdbName,dbName);
01046 if(strcmp(dbName," ")==0)return true;
01047
01048 bool tOk=false;
01049 unsigned int mysqlError;
01050 std::string sdbName(dbName);
01051 size_t found;
01052 found = sdbName.find("blacklist");
01053
01054 if(mysql_select_db(&mData,dbName)){
01055
01056 mysqlError = mysql_errno(&mData);
01057 if(mysqlError==CR_SERVER_GONE_ERROR || mysqlError==CR_SERVER_LOST){
01058 reConnect();
01059 if(mysql_select_db(&mData,dbName)){
01060 if (found == std::string::npos) {
01061 LOG_ERROR<< "Error selecting database=" << dbName << endm;
01062 }
01063 tOk=false;
01064 } else {
01065 tOk=true;
01066 }
01067 } else {
01068 if (found == std::string::npos) {
01069 LOG_ERROR<< "Error selecting database=" << dbName << endm;
01070 }
01071 tOk=false;
01072 }
01073 } else {
01074 tOk=true;
01075 }
01076
01077 return tOk;
01078 }
01079
01081
01082 const MysqlBin *Binary(const unsigned long int aLen,const float *aBin){
01083 static MysqlBin *tBin=0;
01084 static char *tString=0;
01085 unsigned long int tNewLen;
01086
01087 if (!tBin) tBin=new MysqlBin;
01088 if (tString) delete [] tString;
01089
01090 tString = new char[2*aLen+1];
01091 tNewLen = mysql_escape_string(tString,(char*) aBin,aLen);
01092 tBin->Input(tNewLen,tString);
01093 return tBin;
01094 }
01095
01096 #undef __CLASS__
01097
01098