MOOS 0.2375
|
00001 00002 // 00003 // MOOS - Mission Oriented Operating Suite 00004 // 00005 // A suit of Applications and Libraries for Mobile Robotics Research 00006 // Copyright (C) 2001-2005 Massachusetts Institute of Technology and 00007 // Oxford University. 00008 // 00009 // This software was written by Paul Newman at MIT 2001-2002 and Oxford 00010 // University 2003-2005. email: pnewman@robots.ox.ac.uk. 00011 // 00012 // This file is part of a MOOS Core Component. 00013 // 00014 // This program is free software; you can redistribute it and/or 00015 // modify it under the terms of the GNU General Public License as 00016 // published by the Free Software Foundation; either version 2 of the 00017 // License, or (at your option) any later version. 00018 // 00019 // This program is distributed in the hope that it will be useful, 00020 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00022 // General Public License for more details. 00023 // 00024 // You should have received a copy of the GNU General Public License 00025 // along with this program; if not, write to the Free Software 00026 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00027 // 02111-1307, USA. 00028 // 00030 // MOOSDB.cpp: implementation of the CMOOSDB class. 00031 // 00033 00034 #ifdef _WIN32 00035 #pragma warning(disable : 4786) 00036 #endif 00037 00038 00039 #include <MOOSLIB/MOOSLib.h> 00040 #include <MOOSGenLib/MOOSGenLib.h> 00041 00042 #include "MOOSDB.h" 00043 #include "assert.h" 00044 #include <iostream> 00045 #include <sstream> 00046 #include <iterator> 00047 using namespace std; 00048 00050 // Construction/Destruction 00052 00053 00054 00055 bool CMOOSDB::OnRxPktCallBack(const std::string & sWho,MOOSMSG_LIST & MsgListRx,MOOSMSG_LIST & MsgListTx, void * pParam) 00056 { 00057 CMOOSDB* pMe = (CMOOSDB*)(pParam); 00058 00059 return pMe->OnRxPkt(sWho,MsgListRx,MsgListTx); 00060 } 00061 00062 bool CMOOSDB::OnDisconnectCallBack(string & sClient, void * pParam) 00063 { 00064 CMOOSDB* pMe = (CMOOSDB*)(pParam); 00065 00066 return pMe->OnDisconnect(sClient); 00067 } 00068 00069 CMOOSDB::CMOOSDB() 00070 { 00071 //here we set up default community names and DB Names 00072 m_sDBName = "MOOSDB#1"; 00073 m_sCommunityName = "#1"; 00074 00075 //her is the default port to listen on 00076 m_nPort = DEFAULT_MOOS_SERVER_PORT; 00077 00078 //make our own variable called DB_TIME 00079 { 00080 CMOOSDBVar NewVar("DB_TIME"); 00081 NewVar.m_cDataType = MOOS_DOUBLE; 00082 NewVar.m_dfVal= HPMOOSTime(); 00083 NewVar.m_sWhoChangedMe = m_sDBName; 00084 NewVar.m_sOriginatingCommunity = m_sCommunityName; 00085 NewVar.m_dfWrittenTime = HPMOOSTime(); 00086 m_VarMap["DB_TIME"] = NewVar; 00087 } 00088 00089 //make our own variable called DB_TIME 00090 { 00091 CMOOSDBVar NewVar("DB_UPTIME"); 00092 NewVar.m_cDataType = MOOS_DOUBLE; 00093 NewVar.m_dfVal= 0; 00094 NewVar.m_sWhoChangedMe = m_sDBName; 00095 NewVar.m_sOriginatingCommunity = m_sCommunityName; 00096 NewVar.m_dfWrittenTime = HPMOOSTime(); 00097 m_VarMap["DB_UPTIME"] = NewVar; 00098 } 00099 00100 //make our own variable called DB_CLIENTS 00101 { 00102 CMOOSDBVar NewVar("DB_CLIENTS"); 00103 NewVar.m_cDataType = MOOS_DOUBLE; 00104 NewVar.m_dfVal= HPMOOSTime(); 00105 NewVar.m_sWhoChangedMe = m_sDBName; 00106 NewVar.m_sOriginatingCommunity = m_sCommunityName; 00107 NewVar.m_dfWrittenTime = HPMOOSTime(); 00108 m_VarMap["DB_CLIENTS"] = NewVar; 00109 } 00110 00111 //ignore broken pipes as is standard for network apps 00112 #ifndef _WIN32 00113 signal(SIGPIPE,SIG_IGN); 00114 #endif 00115 00116 00117 00118 } 00119 00120 CMOOSDB::~CMOOSDB() 00121 { 00122 00123 } 00124 00125 bool CMOOSDB::Run(const std::string & sMissionFile ) 00126 { 00127 if(!m_MissionReader.SetFile(sMissionFile)) 00128 { 00129 MOOSTrace("Warning no mission file found - still serving but with trepidation\n"); 00130 } 00131 00132 00133 if(m_MissionReader.GetValue("COMMUNITY",m_sCommunityName)) 00134 { 00135 m_sDBName = "MOOSDB_"+m_sCommunityName; 00136 } 00137 00138 double dfWarp; 00139 if(m_MissionReader.GetValue("MOOSTimeWarp",dfWarp)) 00140 { 00141 SetMOOSTimeWarp(dfWarp); 00142 } 00143 00144 //is there a network - default - true 00145 bool bNoNetwork = false; 00146 m_MissionReader.GetValue("NoNetwork",bNoNetwork); 00147 00148 00149 string sPort; 00150 00151 if(m_MissionReader.GetValue("SERVERPORT",sPort)) 00152 { 00153 m_nPort = atoi(sPort.c_str()); 00154 if(m_nPort==0) 00155 { 00156 MOOSTrace("Error reading server port defaulting to %d \n",DEFAULT_MOOS_SERVER_PORT); 00157 m_nPort = DEFAULT_MOOS_SERVER_PORT; 00158 } 00159 } 00160 00161 m_CommServer.SetOnRxCallBack(OnRxPktCallBack,this); 00162 00163 m_CommServer.SetOnDisconnectCallBack(OnDisconnectCallBack,this); 00164 00165 LogStartTime(); 00166 00167 m_CommServer.Run(m_nPort,m_sCommunityName,bNoNetwork); 00168 00169 return true; 00170 } 00171 00172 00173 void CMOOSDB::UpdateDBClientsVar() 00174 { 00175 #define CLIENT_LIST_PUBLISH_PERIOD 2 00176 static double dfLastTime = MOOSTime(); 00177 double dfNow = MOOSTime(); 00178 if(dfNow-dfLastTime>CLIENT_LIST_PUBLISH_PERIOD) 00179 { 00180 STRING_LIST Clients; 00181 m_CommServer.GetClientNames(Clients); 00182 00183 std::ostringstream ss; 00184 std::copy(Clients.begin(),Clients.end(),ostream_iterator<std::string>(ss,",")); 00185 00186 CMOOSMsg DBC(MOOS_NOTIFY,"DB_CLIENTS",ss.str()); 00187 DBC.m_sOriginatingCommunity = m_sCommunityName; 00188 DBC.m_sSrc = m_sDBName; 00189 OnNotify(DBC); 00190 dfLastTime = dfNow; 00191 } 00192 00193 00194 00195 00196 } 00197 00198 void CMOOSDB::UpdateDBTimeVars() 00199 { 00200 static double dfLastTime = MOOSTime(); 00201 double dfNow = MOOSTime(); 00202 if(dfNow-dfLastTime>1.0) 00203 { 00204 CMOOSMsg DBT(MOOS_NOTIFY,"DB_TIME",MOOSTime()); 00205 DBT.m_sOriginatingCommunity = m_sCommunityName; 00206 DBT.m_sSrc = m_sDBName; 00207 OnNotify(DBT); 00208 dfLastTime = dfNow; 00209 00210 CMOOSMsg DBUpT(MOOS_NOTIFY,"DB_UPTIME",MOOSTime()-GetStartTime()); 00211 DBUpT.m_sOriginatingCommunity = m_sCommunityName; 00212 DBUpT.m_sSrc = m_sDBName; 00213 OnNotify(DBUpT); 00214 } 00215 } 00216 00218 bool CMOOSDB::OnRxPkt(const std::string & sClient,MOOSMSG_LIST & MsgListRx,MOOSMSG_LIST & MsgListTx) 00219 { 00220 00221 00222 MOOSMSG_LIST::iterator p; 00223 00224 for(p = MsgListRx.begin();p!=MsgListRx.end();p++) 00225 { 00226 ProcessMsg(*p,MsgListTx); 00227 } 00228 00229 //good spot to update our internal time 00230 UpdateDBTimeVars(); 00231 00232 //and send clients an occasional membersip list 00233 UpdateDBClientsVar(); 00234 00235 if(!MsgListRx.empty()) 00236 { 00237 00238 //now we fill in the packet with our replies to THIS CLIENT 00239 //MOOSMSG_LIST_STRING_MAP::iterator q = m_HeldMailMap.find(MsgListRx.front().m_sSrc); 00240 00241 MOOSMSG_LIST_STRING_MAP::iterator q = m_HeldMailMap.find(sClient); 00242 00243 if(q==m_HeldMailMap.end()) 00244 { 00245 00246 //CMOOSMsg & rMsg = MsgListRx.front(); 00247 //there is no mail waiting to be sent to this client 00248 //should only happen at start up... 00249 //string sClient = MsgListRx.front().m_sSrc; 00250 00251 MOOSMSG_LIST NewList; 00252 00253 m_HeldMailMap[sClient] = NewList; 00254 00255 q = m_HeldMailMap.find(sClient); 00256 00257 assert(q!=m_HeldMailMap.end()); 00258 } 00259 00260 00261 if(q!=m_HeldMailMap.end()) 00262 { 00263 if(!q->second.empty()) 00264 { 00265 //copy all the held mail to MsgListTx 00266 MsgListTx.splice(MsgListTx.begin(),q->second); 00267 } 00268 } 00269 } 00270 00271 return true; 00272 } 00273 00275 bool CMOOSDB::ProcessMsg(CMOOSMsg &MsgRx,MOOSMSG_LIST & MsgListTx) 00276 { 00277 00278 00279 switch(MsgRx.m_cMsgType) 00280 { 00281 case MOOS_NOTIFY: //NOTIFICATION 00282 return OnNotify(MsgRx); 00283 break; 00284 case MOOS_UNREGISTER: 00285 return OnUnRegister(MsgRx); 00286 break; 00287 case MOOS_REGISTER: //REGISTRATION 00288 return OnRegister(MsgRx); 00289 break; 00290 case MOOS_NULL_MSG: 00291 break; 00292 case MOOS_COMMAND: //COMMAND 00293 break; 00294 case MOOS_SERVER_REQUEST: 00295 return DoServerRequest(MsgRx,MsgListTx); 00296 break; 00297 } 00298 00299 return true; 00300 } 00301 00302 00305 bool CMOOSDB::OnNotify(CMOOSMsg &Msg) 00306 { 00307 double dfTimeNow = HPMOOSTime(); 00308 00309 00310 CMOOSDBVar & rVar = GetOrMakeVar(Msg); 00311 00312 00313 if(rVar.m_nWrittenTo==0) 00314 { 00315 rVar.m_cDataType=Msg.m_cDataType; 00316 } 00317 00318 if(rVar.m_cDataType==Msg.m_cDataType) 00319 { 00320 double dfLastWrittenTime = rVar.m_dfWrittenTime; 00321 00322 rVar.m_dfWrittenTime = dfTimeNow; 00323 00324 rVar.m_dfTime = Msg.m_dfTime; 00325 00326 rVar.m_sWhoChangedMe = Msg.m_sSrc; 00327 00328 if(Msg.m_sOriginatingCommunity.empty()) 00329 { 00330 //we are the server in the originating community 00331 rVar.m_sOriginatingCommunity = m_sCommunityName; 00332 Msg.m_sOriginatingCommunity = m_sCommunityName; 00333 } 00334 else 00335 { 00336 //this message came from another community 00337 rVar.m_sOriginatingCommunity = Msg.m_sOriginatingCommunity; 00338 } 00339 00340 switch(rVar.m_cDataType) 00341 { 00342 case MOOS_DOUBLE: 00343 rVar.m_dfVal = Msg.m_dfVal; 00344 break; 00345 case MOOS_STRING: 00346 case MOOS_BINARY_STRING: 00347 rVar.m_sVal = Msg.m_sVal; 00348 break; 00349 } 00350 00351 //record sSrc as a writer of this data 00352 rVar.m_Writers.insert(Msg.m_sSrc); 00353 00354 //increment the number of times we have written to this variable 00355 rVar.m_nWrittenTo++; 00356 00357 //how often is it being written? 00358 double dfDT = (dfTimeNow-dfLastWrittenTime); 00359 if(dfDT>0) 00360 { 00361 //this looks a little hookey - the numbers are arbitrary to give sensible 00362 //looking frequencies when timing is coarse 00363 if(dfDT>10.0) 00364 { 00365 //MIN 00366 rVar.m_dfWriteFreq = 0.0; 00367 } 00368 //else if(dfDT<0.005) 00369 //{ 00370 //MAX OUT 00371 //this is almost certainly two of tge same mesages arrive in the same commpkt - ignore... 00372 //MOOSTrace("Msg %s was last updated at %f and its now %f\n", Msg.GetKey().c_str(),dfTimeNow,dfLastWrittenTime); 00373 //rVar.m_dfWriteFreq = 200.0; 00374 //} 00375 else 00376 { 00377 //IIR FILTER COOEFFICENT 00378 double dfAlpha = 0.95; 00379 rVar.m_dfWriteFreq = dfAlpha*rVar.m_dfWriteFreq + (1.0-dfAlpha)/(dfDT/++rVar.m_nOverTicks); 00380 rVar.m_nOverTicks=0; 00381 } 00382 } 00383 else 00384 { 00385 rVar.m_nOverTicks++; 00386 } 00387 00388 //now comes the intersting part... 00389 //which clients have asked to be informed 00390 //of changes in this variable? 00391 REGISTER_INFO_MAP::iterator p; 00392 00393 00394 for(p = rVar.m_Subscribers.begin();p!=rVar.m_Subscribers.end();p++) 00395 { 00396 00397 CMOOSRegisterInfo & rInfo = p->second; 00398 //has enough time expired since the last time we 00399 //sent notification for the variable? 00400 if(rInfo.Expired(dfTimeNow)) 00401 { 00402 00403 string & sClient = p->second.m_sClientName; 00404 00405 //the Msg we were passed has all the information we require already 00406 Msg.m_cMsgType = MOOS_NOTIFY; 00407 00408 00409 AddMessageToClientBox(sClient,Msg); 00410 00411 //finally we remember when we sent this to the client in question 00412 rInfo.SetLastTimeSent(dfTimeNow); 00413 } 00414 } 00415 } 00416 else 00417 { 00418 MOOSTrace("Attempting to update var \"%s\" which is type %c with data type %c\n", 00419 Msg.m_sKey.c_str(), 00420 rVar.m_cDataType, 00421 Msg.m_cDataType); 00422 } 00423 00424 00425 00426 return true; 00427 } 00428 00429 00432 bool CMOOSDB::AddMessageToClientBox(const string &sClient,CMOOSMsg & Msg) 00433 { 00434 MOOSMSG_LIST_STRING_MAP::iterator q = m_HeldMailMap.find(sClient); 00435 00436 if(q==m_HeldMailMap.end()) 00437 { 00438 //there is no mail waiting to be sent to this client 00439 //should only happen at start up... 00440 MOOSMSG_LIST NewList; 00441 m_HeldMailMap[sClient] = NewList; 00442 00443 q = m_HeldMailMap.find(sClient); 00444 00445 assert(q!=m_HeldMailMap.end()); 00446 } 00447 00448 //q->second is now a reference to a list of messages that will be 00449 //sent to sClient the next time it calls into the database... 00450 00451 q->second.push_front(Msg); 00452 00453 return true; 00454 } 00455 00456 00459 bool CMOOSDB::OnUnRegister(CMOOSMsg &Msg) 00460 { 00461 //what are we looking to un register for? 00462 00463 //if the variable already exists then post a notification message 00464 //to the client 00465 bool bAlreadyThere = VariableExists(Msg.m_sKey); 00466 if(bAlreadyThere) 00467 { 00468 CMOOSDBVar & rVar = GetOrMakeVar(Msg); 00469 rVar.RemoveSubscriber(Msg.m_sSrc); 00470 } 00471 00472 return true; 00473 } 00474 00475 00478 bool CMOOSDB::OnRegister(CMOOSMsg &Msg) 00479 { 00480 00481 00482 //what are we looking to register for? 00483 00484 //if the variable already exists then post a notification message 00485 //to the client 00486 bool bAlreadyThere = VariableExists(Msg.m_sKey); 00487 00488 CMOOSDBVar & rVar = GetOrMakeVar(Msg); 00489 00490 if(!rVar.AddSubscriber(Msg.m_sSrc,Msg.m_dfVal)) 00491 return false; 00492 00493 00494 if(bAlreadyThere && rVar.m_nWrittenTo!=0) 00495 { 00496 //when the client registered the variable already existed... 00497 //better tell them 00498 CMOOSMsg ReplyMsg; 00499 Var2Msg(rVar,ReplyMsg); 00500 00501 ReplyMsg.m_cMsgType = MOOS_NOTIFY; 00502 00503 AddMessageToClientBox(Msg.m_sSrc,ReplyMsg); 00504 00505 } 00506 00507 return true; 00508 } 00509 00510 00515 CMOOSDBVar & CMOOSDB::GetOrMakeVar(CMOOSMsg &Msg) 00516 { 00517 00518 //look up this variable name 00519 DBVAR_MAP::iterator p = m_VarMap.find(Msg.m_sKey); 00520 00521 if(p==m_VarMap.end()) 00522 { 00523 //we need to make a new variable here for this key 00524 //as we don't know about it! 00525 00526 CMOOSDBVar NewVar(Msg.m_sKey); 00527 00528 if(Msg.m_cMsgType==MOOS_REGISTER) 00529 { 00530 //interesting case is when this method is being used to 00531 //register for a variable that has not been written to. Here 00532 //we simply make the variable but don't commit to its data type 00533 NewVar.m_cDataType = MOOS_NOT_SET; 00534 } 00535 else 00536 { 00537 //new variable will have data type of request message 00538 NewVar.m_cDataType = Msg.m_cDataType; 00539 } 00540 00541 //index our new creation 00542 m_VarMap[Msg.m_sKey] = NewVar; 00543 00544 //check we can get it back ok!! 00545 p = m_VarMap.find(Msg.m_sKey); 00546 00547 assert(p!=m_VarMap.end()); 00548 00549 #ifdef DB_VERBOSE 00550 00551 MOOSTrace("\nMaking new variable: \n"); 00552 MOOSTrace(" Name=\"%s\"\n",NewVar.m_sName.c_str()); 00553 MOOSTrace(" Src =\"%s\"\n",Msg.m_sSrc.c_str()); 00554 MOOSTrace(" Type =\"%s\"\n",NewVar.m_cDataType); 00555 #endif 00556 } 00557 00558 //ok we know what you are talking about 00559 CMOOSDBVar & rVar = p->second; 00560 00561 //return the reference 00562 return rVar; 00563 } 00564 00565 bool CMOOSDB::OnDisconnect(string &sClient) 00566 { 00567 //for all variables remove subscriptions to sClient 00568 00569 DBVAR_MAP::iterator p; 00570 00571 for(p=m_VarMap.begin();p!=m_VarMap.end();p++) 00572 { 00573 CMOOSDBVar & rVar = p->second; 00574 00575 rVar.RemoveSubscriber(sClient); 00576 } 00577 00578 MOOSTrace("removing held mail for \"%s\"...\n",sClient.c_str()); 00579 00580 m_HeldMailMap.erase(sClient); 00581 00582 return true; 00583 } 00584 00585 bool CMOOSDB::DoServerRequest(CMOOSMsg &Msg, MOOSMSG_LIST &MsgTxList) 00586 { 00587 //explictly requesting the server to do something... 00588 00589 if(Msg.m_sKey=="ALL") 00590 { 00591 return OnServerAllRequested(Msg,MsgTxList); 00592 } 00593 else if(Msg.m_sKey.find("PROC_SUMMARY")!=string::npos) 00594 { 00595 return OnProcessSummaryRequested(Msg,MsgTxList); 00596 } 00597 else if (Msg.m_sKey.find("VAR_SUMMARY") != string::npos) 00598 { 00599 return OnVarSummaryRequested(Msg, MsgTxList); 00600 } 00601 else if(Msg.m_sKey.find("DB_CLEAR")!=string::npos) 00602 { 00603 return OnClearRequested(Msg,MsgTxList); 00604 } 00605 00606 00607 00608 return false; 00609 } 00610 00611 bool CMOOSDB::OnProcessSummaryRequested(CMOOSMsg &Msg, MOOSMSG_LIST &MsgTxList) 00612 { 00613 DBVAR_MAP::iterator p; 00614 STRING_LIST::iterator q; 00615 00616 STRING_LIST Clients; 00617 00618 m_CommServer.GetClientNames(Clients); 00619 00620 00621 for(q=Clients.begin();q!=Clients.end();q++) 00622 { 00623 string sWho = *q; 00624 00625 string sPublished= "PUBLISHED="; 00626 string sSubscribed = "SUBSCRIBED="; 00627 00628 for(p=m_VarMap.begin();p!=m_VarMap.end();p++) 00629 { 00630 CMOOSDBVar & rVar = p->second; 00631 00632 if(rVar.m_Writers.find(sWho)!=rVar.m_Writers.end()) 00633 { 00634 if(!sPublished.empty()) 00635 { 00636 sPublished+=","; 00637 } 00638 sPublished+=rVar.m_sName; 00639 00640 } 00641 00642 if(rVar.m_Subscribers.find(sWho)!=rVar.m_Subscribers.end()) 00643 { 00644 if(!sSubscribed.empty()) 00645 { 00646 sSubscribed+=","; 00647 } 00648 sSubscribed+=rVar.m_sName; 00649 } 00650 } 00651 00652 00653 CMOOSMsg MsgReply; 00654 00655 MsgReply.m_nID = Msg.m_nID; 00656 00657 MsgReply.m_cMsgType = MOOS_NOTIFY; 00658 MsgReply.m_cDataType = MOOS_STRING; 00659 MsgReply.m_dfTime = MOOSTime()-m_dfStartTime; //for display 00660 MsgReply.m_sSrc = m_sDBName; 00661 MsgReply.m_sKey = "PROC_SUMMARY"; 00662 MsgReply.m_sVal = sWho+":"+sSubscribed+","+sPublished; 00663 MsgReply.m_dfVal = -1; 00664 00665 00666 MsgTxList.push_front(MsgReply); 00667 } 00668 00669 return true; 00670 00671 } 00672 00673 bool CMOOSDB::OnServerAllRequested(CMOOSMsg &Msg, MOOSMSG_LIST &MsgTxList) 00674 { 00675 00676 00677 DBVAR_MAP::iterator p; 00678 00679 for(p=m_VarMap.begin();p!=m_VarMap.end();p++) 00680 { 00681 CMOOSDBVar & rVar = p->second; 00682 00683 CMOOSMsg MsgVar; 00684 00685 MsgVar.m_nID = Msg.m_nID; 00686 00687 MsgVar.m_cMsgType = MOOS_NOTIFY; 00688 MsgVar.m_cDataType = rVar.m_cDataType; 00689 MsgVar.m_dfTime = rVar.m_dfWrittenTime-m_dfStartTime; //for display 00690 MsgVar.m_sSrc = rVar.m_sWhoChangedMe; 00691 MsgVar.m_sKey = rVar.m_sName; 00692 MsgVar.m_sVal = rVar.m_sVal; 00693 MsgVar.m_sSrcAux = rVar.m_sSrcAux; 00694 MsgVar.m_dfVal = rVar.m_dfVal; 00695 MsgVar.m_dfVal2 = rVar.m_dfWriteFreq; 00696 MsgVar.m_sOriginatingCommunity = rVar.m_sOriginatingCommunity; 00697 00698 if(MsgVar.m_dfTime<0) 00699 { 00700 MsgVar.m_dfTime =-1; 00701 } 00702 00703 MsgTxList.push_front(MsgVar); 00704 00705 00706 } 00707 00708 00709 return true; 00710 } 00711 00712 //Suggested addition by MIT users 2006 - shorter version of OnProcessSummary 00713 bool CMOOSDB::OnVarSummaryRequested(CMOOSMsg &Msg, MOOSMSG_LIST &MsgTxList) 00714 { 00715 std::string TheVars; 00716 DBVAR_MAP::iterator p; 00717 for(p = m_VarMap.begin(); p != m_VarMap.end(); p++) 00718 { 00719 //look to a comma 00720 if(p!=m_VarMap.begin()) 00721 TheVars += ","; 00722 00723 TheVars += p->first; 00724 } 00725 00726 CMOOSMsg Reply; 00727 00728 //so the client knows the query result correspondences 00729 Reply.m_nID = Msg.m_nID; 00730 Reply.m_cMsgType = MOOS_NOTIFY; 00731 Reply.m_cDataType = MOOS_STRING; 00732 Reply.m_dfTime = MOOSTime(); 00733 Reply.m_sSrc = m_sDBName; 00734 Reply.m_sKey = "VAR_SUMMARY"; 00735 Reply.m_sVal = TheVars; 00736 Reply.m_dfVal = -1; 00737 00738 MsgTxList.push_front(Reply); 00739 00740 return true; 00741 } 00742 00743 00744 00745 00746 00747 bool CMOOSDB::OnClearRequested(CMOOSMsg &Msg, MOOSMSG_LIST &MsgTxList) 00748 { 00749 MOOSTrace("Clear Down Requested:\n"); 00750 00751 MOOSTrace(" Resetting %d variables...",m_VarMap.size()); 00752 00753 DBVAR_MAP::iterator p; 00754 00755 for(p = m_VarMap.begin();p!=m_VarMap.end();p++) 00756 { 00757 CMOOSDBVar & rVar = p->second; 00758 rVar.Reset(); 00759 } 00760 MOOSTrace("done\n"); 00761 00762 00763 MOOSTrace(" Removing %d existing notification queues...",m_HeldMailMap.size()); 00764 MOOSMSG_LIST_STRING_MAP::iterator q; 00765 00766 for(q = m_HeldMailMap.begin();q!=m_HeldMailMap.end();q++) 00767 { 00768 MOOSMSG_LIST & rList = q->second; 00769 rList.clear(); 00770 } 00771 MOOSTrace("done\n"); 00772 00773 //MOOSTrace(" resetting DB start Time...done\n"); 00774 LogStartTime(); 00775 00776 00777 return true; 00778 00779 } 00780 00781 00782 void CMOOSDB::LogStartTime() 00783 { 00784 m_dfStartTime = MOOSTime(); 00785 00786 return; 00787 string sKey = "DB_START_TIME"; 00788 00789 00790 DBVAR_MAP::iterator p = m_VarMap.find("DB_START_TIME"); 00791 00792 if(p==m_VarMap.end()) 00793 { 00794 00795 CMOOSDBVar NewVar(sKey); 00796 00797 NewVar.m_cDataType = MOOS_DOUBLE; 00798 NewVar.m_dfVal = m_dfStartTime; 00799 NewVar.m_dfTime = m_dfStartTime; 00800 NewVar.m_sWhoChangedMe = m_sDBName; 00801 NewVar.m_sOriginatingCommunity = m_sCommunityName; 00802 00803 m_VarMap[sKey] = NewVar; 00804 00805 } 00806 else 00807 { 00808 CMOOSDBVar & rVar = p->second; 00809 rVar.m_dfVal = m_dfStartTime; 00810 rVar.m_dfTime = m_dfStartTime; 00811 } 00812 00813 } 00814 00815 00816 00817 bool CMOOSDB::VariableExists(const string &sVar) 00818 { 00819 DBVAR_MAP::iterator p=m_VarMap.find(sVar); 00820 00821 return (!m_VarMap.empty()) && (p!=m_VarMap.end()); 00822 } 00823 00824 void CMOOSDB::Var2Msg(CMOOSDBVar &Var, CMOOSMsg &Msg) 00825 { 00826 Msg.m_dfTime = Var.m_dfTime; 00827 Msg.m_cDataType = Var.m_cDataType; 00828 Msg.m_sSrc = Var.m_sWhoChangedMe; 00829 Msg.m_sKey = Var.m_sName; 00830 Msg.m_sOriginatingCommunity = Var.m_sOriginatingCommunity; 00831 switch(Var.m_cDataType) 00832 { 00833 case MOOS_DOUBLE: 00834 Msg.m_dfVal = Var.m_dfVal; 00835 break; 00836 case MOOS_STRING: 00837 case MOOS_BINARY_STRING: 00838 Msg.m_sVal = Var.m_sVal; 00839 break; 00840 } 00841 } 00842 00843