|
reSIProcate/repro
9694
|
00001 #include <cassert> 00002 00003 #include "rutil/Data.hxx" 00004 #include "rutil/DataStream.hxx" 00005 #include "rutil/ParseBuffer.hxx" 00006 #include "resip/stack/Symbols.hxx" 00007 #include "rutil/Logger.hxx" 00008 00009 00010 #include "repro/UserStore.hxx" 00011 #include "repro/AbstractDb.hxx" 00012 00013 00014 using namespace resip; 00015 using namespace repro; 00016 using namespace std; 00017 00018 #define RESIPROCATE_SUBSYSTEM Subsystem::REPRO 00019 00020 00021 static void 00022 encodeString(oDataStream& s, const Data& data) 00023 { 00024 short len = (short)data.size(); 00025 s.write( (char*)(&len) , sizeof( len ) ); 00026 s.write( data.data(), len ); 00027 } 00028 00029 00030 static void 00031 decodeString(iDataStream& s, Data& data) 00032 { 00033 data.clear(); 00034 00035 if(s.eof()) return; 00036 00037 short len; 00038 s.read((char*)(&len), sizeof(len)); 00039 if(s.eof()) return; 00040 00041 // [TODO] This is probably OK for now, but we can do better than this. 00042 if (len > 8192) 00043 { 00044 ErrLog( << "Tried to decode a database record that was much larger (>8k) than expected. Returning an empty Data instead." ); 00045 return; 00046 } 00047 00048 s.read(data.getBuf(len), len); 00049 } 00050 00051 00052 AbstractDb::AbstractDb() 00053 { 00054 } 00055 00056 00057 AbstractDb::~AbstractDb() 00058 { 00059 } 00060 00061 00062 Data 00063 AbstractDb::dbFirstKey(const AbstractDb::Table table) 00064 { 00065 return dbNextKey(table,true/*first*/); 00066 } 00067 00068 00069 bool 00070 AbstractDb::dbFirstRecord(const AbstractDb::Table table, 00071 const Data& key, 00072 Data& data, 00073 bool forUpdate) 00074 { 00075 return dbNextRecord(table, key, data, forUpdate, true/*first*/); 00076 } 00077 00078 00079 // Callback used by BerkeleyDb for secondary table support. Returns key to use in 00080 // secondary database table 00081 // secondaryKey should point to persistent data (ie. typically something from data itself) 00082 int 00083 AbstractDb::getSecondaryKey(const Table table, 00084 const Key& key, 00085 const Data& data, 00086 void** secondaryKey, 00087 unsigned int* secondaryKeyLen) 00088 { 00089 if(table == SiloTable) 00090 { 00091 // Secondary Key for Silo table is DestUri 00092 Data nonConstData(Data::Share, data.data(), data.size()); 00093 iDataStream s(nonConstData); 00094 00095 short version; 00096 assert(sizeof(version) == 2); 00097 s.read((char*)(&version), sizeof(version)); 00098 assert(version == 1); 00099 if (version == 1) 00100 { 00101 // DestUri is first element after version 00102 short len; 00103 s.read( (char*)(&len), sizeof(len)); 00104 *secondaryKeyLen = (unsigned int)len; 00105 *secondaryKey = (void*)(nonConstData.data() + (sizeof(version)+sizeof(len))); 00106 return 0; 00107 } 00108 } 00109 return -1; 00110 } 00111 00112 00113 void 00114 AbstractDb::encodeUser(const UserRecord& rec, resip::Data& data) 00115 { 00116 oDataStream s(data); 00117 00118 short version=2; 00119 assert( sizeof( version) == 2 ); 00120 s.write( (char*)(&version) , sizeof(version) ); 00121 00122 encodeString( s, rec.user ); 00123 encodeString( s, rec.domain); 00124 encodeString( s, rec.realm); 00125 encodeString( s, rec.passwordHash); 00126 encodeString( s, rec.name); 00127 encodeString( s, rec.email); 00128 encodeString( s, rec.forwardAddress); 00129 s.flush(); 00130 } 00131 00132 bool 00133 AbstractDb::addUser( const AbstractDb::Key& key, const AbstractDb::UserRecord& rec ) 00134 { 00135 assert( !key.empty() ); 00136 00137 Data data; 00138 encodeUser(rec, data); 00139 00140 return dbWriteRecord(UserTable,key,data); 00141 } 00142 00143 00144 void 00145 AbstractDb::eraseUser( const AbstractDb::Key& key ) 00146 { 00147 dbEraseRecord( UserTable, key); 00148 } 00149 00150 00151 AbstractDb::UserRecord 00152 AbstractDb::getUser( const AbstractDb::Key& key ) const 00153 { 00154 AbstractDb::UserRecord rec; 00155 Data data; 00156 bool stat = dbReadRecord( UserTable, key, data ); 00157 if ( !stat ) 00158 { 00159 return rec; 00160 } 00161 if ( data.empty() ) 00162 { 00163 return rec; 00164 } 00165 00166 iDataStream s(data); 00167 00168 short version; 00169 assert( sizeof(version) == 2 ); 00170 s.read( (char*)(&version), sizeof(version) ); 00171 00172 if ( version == 2 ) 00173 { 00174 decodeString(s, rec.user); 00175 decodeString(s, rec.domain); 00176 decodeString(s, rec.realm); 00177 decodeString(s, rec.passwordHash); 00178 decodeString(s, rec.name); 00179 decodeString(s, rec.email); 00180 decodeString(s, rec.forwardAddress); 00181 } 00182 else 00183 { 00184 // unknown version 00185 ErrLog( <<"Data in user database with unknown version " << version ); 00186 ErrLog( <<"record size is " << data.size() ); 00187 } 00188 00189 return rec; 00190 } 00191 00192 00193 Data 00194 AbstractDb::getUserAuthInfo( const AbstractDb::Key& key ) const 00195 { 00196 AbstractDb::UserRecord rec = getUser(key); 00197 00198 return rec.passwordHash; 00199 } 00200 00201 00202 AbstractDb::Key 00203 AbstractDb::firstUserKey() 00204 { 00205 return dbFirstKey(UserTable); 00206 } 00207 00208 00209 AbstractDb::Key 00210 AbstractDb::nextUserKey() 00211 { 00212 return dbNextKey(UserTable); 00213 } 00214 00215 00216 void 00217 AbstractDb::encodeRoute(const RouteRecord& rec, resip::Data& data) 00218 { 00219 oDataStream s(data); 00220 00221 short version=1; 00222 assert( sizeof( version) == 2 ); 00223 s.write( (char*)(&version) , sizeof(version) ); 00224 00225 encodeString( s, rec.mMethod ); 00226 encodeString( s, rec.mEvent ); 00227 encodeString( s, rec.mMatchingPattern ); 00228 encodeString( s, rec.mRewriteExpression ); 00229 s.write( (char*)(&rec.mOrder) , sizeof( rec.mOrder ) ); 00230 assert( sizeof( rec.mOrder) == 2 ); 00231 00232 //!cj! TODO - add the extra local use only flag 00233 00234 s.flush(); 00235 } 00236 00237 00238 bool 00239 AbstractDb::addRoute( const AbstractDb::Key& key, 00240 const AbstractDb::RouteRecord& rec ) 00241 { 00242 assert( !key.empty() ); 00243 00244 Data data; 00245 encodeRoute(rec, data); 00246 00247 return dbWriteRecord( RouteTable, key, data ); 00248 } 00249 00250 00251 void 00252 AbstractDb::eraseRoute( const AbstractDb::Key& key ) 00253 { 00254 dbEraseRecord (RouteTable, key); 00255 } 00256 00257 00258 AbstractDb::RouteRecord 00259 AbstractDb::getRoute( const AbstractDb::Key& key) const 00260 { 00261 AbstractDb::RouteRecord rec; 00262 Data data; 00263 bool stat = dbReadRecord( RouteTable, key, data ); 00264 if ( !stat ) 00265 { 00266 return rec; 00267 } 00268 if ( data.empty() ) 00269 { 00270 return rec; 00271 } 00272 00273 iDataStream s(data); 00274 00275 short version; 00276 assert( sizeof(version) == 2 ); 00277 s.read( (char*)(&version), sizeof(version) ); 00278 00279 if ( version == 1 ) 00280 { 00281 decodeString(s, rec.mMethod); 00282 decodeString(s, rec.mEvent); 00283 decodeString(s, rec.mMatchingPattern); 00284 decodeString(s, rec.mRewriteExpression); 00285 s.read( (char*)(&rec.mOrder), sizeof(rec.mOrder) ); 00286 assert( sizeof( rec.mOrder) == 2 ); 00287 } 00288 else 00289 { 00290 // unknown version 00291 ErrLog( <<"Data in route database with unknown version " << version ); 00292 ErrLog( <<"record size is " << data.size() ); 00293 } 00294 00295 return rec; 00296 } 00297 00298 00299 AbstractDb::RouteRecordList 00300 AbstractDb::getAllRoutes() 00301 { 00302 AbstractDb::RouteRecordList ret; 00303 00304 AbstractDb::Key key = firstRouteKey(); 00305 while ( !key.empty() ) 00306 { 00307 AbstractDb::RouteRecord rec = getRoute(key); 00308 00309 ret.push_back(rec); 00310 00311 key = nextRouteKey(); 00312 } 00313 00314 return ret; 00315 } 00316 00317 00318 AbstractDb::Key 00319 AbstractDb::firstRouteKey() 00320 { 00321 return dbFirstKey(RouteTable); 00322 } 00323 00324 00325 AbstractDb::Key 00326 AbstractDb::nextRouteKey() 00327 { 00328 return dbNextKey(RouteTable); 00329 } 00330 00331 00332 bool 00333 AbstractDb::addAcl( const AbstractDb::Key& key, 00334 const AbstractDb::AclRecord& rec ) 00335 { 00336 assert( !key.empty() ); 00337 00338 Data data; 00339 { 00340 oDataStream s(data); 00341 00342 short version=1; 00343 assert( sizeof( version) == 2 ); 00344 s.write( (char*)(&version) , sizeof(version) ); 00345 00346 encodeString( s, rec.mTlsPeerName ); 00347 encodeString( s, rec.mAddress ); 00348 s.write( (char*)(&rec.mMask) , sizeof( rec.mMask ) ); 00349 s.write( (char*)(&rec.mPort) , sizeof( rec.mPort ) ); 00350 s.write( (char*)(&rec.mFamily) , sizeof( rec.mFamily ) ); 00351 s.write( (char*)(&rec.mTransport) , sizeof( rec.mTransport ) ); 00352 00353 s.flush(); 00354 } 00355 00356 return dbWriteRecord( AclTable, key, data ); 00357 } 00358 00359 00360 void 00361 AbstractDb::eraseAcl( const AbstractDb::Key& key ) 00362 { 00363 dbEraseRecord (AclTable, key); 00364 } 00365 00366 00367 AbstractDb::AclRecord 00368 AbstractDb::getAcl( const AbstractDb::Key& key) const 00369 { 00370 AbstractDb::AclRecord rec; 00371 Data data; 00372 bool stat = dbReadRecord( AclTable, key, data ); 00373 if ( !stat ) 00374 { 00375 return rec; 00376 } 00377 if ( data.empty() ) 00378 { 00379 return rec; 00380 } 00381 00382 iDataStream s(data); 00383 00384 short version; 00385 assert( sizeof(version) == 2 ); 00386 s.read( (char*)(&version), sizeof(version) ); 00387 00388 if ( version == 1 ) 00389 { 00390 decodeString(s, rec.mTlsPeerName); 00391 decodeString(s, rec.mAddress); 00392 s.read( (char*)(&rec.mMask), sizeof(rec.mMask) ); 00393 s.read( (char*)(&rec.mPort), sizeof(rec.mPort) ); 00394 s.read( (char*)(&rec.mFamily), sizeof(rec.mFamily) ); 00395 s.read( (char*)(&rec.mTransport), sizeof(rec.mTransport) ); 00396 } 00397 else 00398 { 00399 // unknown version 00400 ErrLog( <<"Data in ACL database with unknown version " << version ); 00401 ErrLog( <<"record size is " << data.size() ); 00402 } 00403 00404 return rec; 00405 } 00406 00407 00408 AbstractDb::AclRecordList 00409 AbstractDb::getAllAcls() 00410 { 00411 AbstractDb::AclRecordList ret; 00412 00413 AbstractDb::Key key = firstAclKey(); 00414 while ( !key.empty() ) 00415 { 00416 AbstractDb::AclRecord rec = getAcl(key); 00417 00418 ret.push_back(rec); 00419 00420 key = nextAclKey(); 00421 } 00422 00423 return ret; 00424 } 00425 00426 00427 AbstractDb::Key 00428 AbstractDb::firstAclKey() 00429 { 00430 return dbFirstKey(AclTable); 00431 } 00432 00433 00434 AbstractDb::Key 00435 AbstractDb::nextAclKey() 00436 { 00437 return dbNextKey(AclTable); 00438 } 00439 00440 00441 bool 00442 AbstractDb::addConfig( const AbstractDb::Key& key, 00443 const AbstractDb::ConfigRecord& rec ) 00444 { 00445 assert( !key.empty() ); 00446 00447 Data data; 00448 { 00449 oDataStream s(data); 00450 00451 short version=1; 00452 assert( sizeof( version) == 2 ); 00453 s.write( (char*)(&version) , sizeof(version) ); 00454 00455 encodeString( s, rec.mDomain ); 00456 s.write( (char*)(&rec.mTlsPort) , sizeof( rec.mTlsPort ) ); 00457 assert( sizeof(rec.mTlsPort) == 2 ); 00458 00459 s.flush(); 00460 } 00461 00462 return dbWriteRecord( ConfigTable, key, data ); 00463 } 00464 00465 00466 void 00467 AbstractDb::eraseConfig( const AbstractDb::Key& key ) 00468 { 00469 dbEraseRecord (ConfigTable, key); 00470 } 00471 00472 00473 AbstractDb::ConfigRecord 00474 AbstractDb::getConfig( const AbstractDb::Key& key) const 00475 { 00476 AbstractDb::ConfigRecord rec; 00477 Data data; 00478 bool stat = dbReadRecord( ConfigTable, key, data ); 00479 if ( !stat ) 00480 { 00481 return rec; 00482 } 00483 if ( data.empty() ) 00484 { 00485 return rec; 00486 } 00487 00488 iDataStream s(data); 00489 00490 short version; 00491 assert( sizeof(version) == 2 ); 00492 s.read( (char*)(&version), sizeof(version) ); 00493 00494 if ( version == 1 ) 00495 { 00496 decodeString(s, rec.mDomain); 00497 00498 s.read( (char*)(&rec.mTlsPort), sizeof(rec.mTlsPort) ); 00499 assert( sizeof( rec.mTlsPort) == 2 ); 00500 } 00501 else 00502 { 00503 // unknown version 00504 ErrLog( <<"Data in ACL database with unknown version " << version ); 00505 ErrLog( <<"record size is " << data.size() ); 00506 } 00507 00508 return rec; 00509 } 00510 00511 00512 AbstractDb::ConfigRecordList 00513 AbstractDb::getAllConfigs() 00514 { 00515 AbstractDb::ConfigRecordList ret; 00516 00517 AbstractDb::Key key = firstConfigKey(); 00518 while ( !key.empty() ) 00519 { 00520 AbstractDb::ConfigRecord rec = getConfig(key); 00521 00522 ret.push_back(rec); 00523 00524 key = nextConfigKey(); 00525 } 00526 00527 return ret; 00528 } 00529 00530 00531 AbstractDb::Key 00532 AbstractDb::firstConfigKey() 00533 { 00534 return dbFirstKey(ConfigTable); 00535 } 00536 00537 00538 AbstractDb::Key 00539 AbstractDb::nextConfigKey() 00540 { 00541 return dbNextKey(ConfigTable); 00542 } 00543 00544 00545 bool 00546 AbstractDb::addStaticReg( const AbstractDb::Key& key, 00547 const AbstractDb::StaticRegRecord& rec ) 00548 { 00549 assert( !key.empty() ); 00550 00551 Data data; 00552 { 00553 oDataStream s(data); 00554 00555 short version=1; 00556 assert( sizeof( version) == 2 ); 00557 s.write( (char*)(&version) , sizeof(version) ); 00558 00559 encodeString( s, rec.mAor ); 00560 encodeString( s, rec.mContact ); 00561 encodeString( s, rec.mPath ); 00562 00563 s.flush(); 00564 } 00565 00566 return dbWriteRecord( StaticRegTable, key, data ); 00567 } 00568 00569 00570 void 00571 AbstractDb::eraseStaticReg( const AbstractDb::Key& key ) 00572 { 00573 dbEraseRecord (StaticRegTable, key); 00574 } 00575 00576 00577 AbstractDb::StaticRegRecord 00578 AbstractDb::getStaticReg( const AbstractDb::Key& key) const 00579 { 00580 AbstractDb::StaticRegRecord rec; 00581 Data data; 00582 bool stat = dbReadRecord( StaticRegTable, key, data ); 00583 if ( !stat ) 00584 { 00585 return rec; 00586 } 00587 if ( data.empty() ) 00588 { 00589 return rec; 00590 } 00591 00592 iDataStream s(data); 00593 00594 short version; 00595 assert( sizeof(version) == 2 ); 00596 s.read( (char*)(&version), sizeof(version) ); 00597 00598 if ( version == 1 ) 00599 { 00600 decodeString(s, rec.mAor); 00601 decodeString(s, rec.mContact); 00602 decodeString(s, rec.mPath); 00603 } 00604 else 00605 { 00606 // unknown version 00607 ErrLog( <<"Data in StaticReg database with unknown version " << version ); 00608 ErrLog( <<"record size is " << data.size() ); 00609 } 00610 00611 return rec; 00612 } 00613 00614 00615 AbstractDb::StaticRegRecordList 00616 AbstractDb::getAllStaticRegs() 00617 { 00618 AbstractDb::StaticRegRecordList ret; 00619 00620 AbstractDb::Key key = firstStaticRegKey(); 00621 while ( !key.empty() ) 00622 { 00623 AbstractDb::StaticRegRecord rec = getStaticReg(key); 00624 00625 ret.push_back(rec); 00626 00627 key = nextStaticRegKey(); 00628 } 00629 00630 return ret; 00631 } 00632 00633 00634 AbstractDb::Key 00635 AbstractDb::firstStaticRegKey() 00636 { 00637 return dbFirstKey(StaticRegTable); 00638 } 00639 00640 00641 AbstractDb::Key 00642 AbstractDb::nextStaticRegKey() 00643 { 00644 return dbNextKey(StaticRegTable); 00645 } 00646 00647 00648 void 00649 AbstractDb::encodeFilter(const FilterRecord& rec, resip::Data& data) 00650 { 00651 oDataStream s(data); 00652 00653 short version=1; 00654 assert(sizeof( version) == 2); 00655 s.write((char*)(&version) , sizeof(version)); 00656 00657 encodeString(s, rec.mCondition1Header); 00658 encodeString(s, rec.mCondition1Regex); 00659 encodeString(s, rec.mCondition2Header); 00660 encodeString(s, rec.mCondition2Regex); 00661 encodeString(s, rec.mMethod); 00662 encodeString(s, rec.mEvent); 00663 s.write((char*)(&rec.mAction), sizeof (rec.mAction)); 00664 assert(sizeof(rec.mAction) == 2); 00665 encodeString(s, rec.mActionData); 00666 s.write((char*)(&rec.mOrder), sizeof(rec.mOrder)); 00667 assert(sizeof(rec.mOrder) == 2); 00668 00669 s.flush(); 00670 } 00671 00672 00673 bool 00674 AbstractDb::addFilter(const AbstractDb::Key& key, 00675 const AbstractDb::FilterRecord& rec) 00676 { 00677 assert( !key.empty() ); 00678 00679 Data data; 00680 encodeFilter(rec, data); 00681 return dbWriteRecord(FilterTable, key, data); 00682 } 00683 00684 00685 void 00686 AbstractDb::eraseFilter(const AbstractDb::Key& key) 00687 { 00688 dbEraseRecord(FilterTable, key); 00689 } 00690 00691 00692 AbstractDb::FilterRecord 00693 AbstractDb::getFilter( const AbstractDb::Key& key) const 00694 { 00695 AbstractDb::FilterRecord rec; 00696 Data data; 00697 bool stat = dbReadRecord(FilterTable, key, data); 00698 if (!stat) 00699 { 00700 return rec; 00701 } 00702 if (data.empty()) 00703 { 00704 return rec; 00705 } 00706 00707 iDataStream s(data); 00708 00709 short version; 00710 assert(sizeof(version) == 2); 00711 s.read((char*)(&version), sizeof(version)); 00712 00713 if (version == 1) 00714 { 00715 decodeString(s, rec.mCondition1Header); 00716 decodeString(s, rec.mCondition1Regex); 00717 decodeString(s, rec.mCondition2Header); 00718 decodeString(s, rec.mCondition2Regex); 00719 decodeString(s, rec.mMethod); 00720 decodeString(s, rec.mEvent); 00721 s.read((char*)(&rec.mAction), sizeof(rec.mAction)); 00722 assert(sizeof(rec.mAction) == 2); 00723 decodeString(s, rec.mActionData); 00724 s.read((char*)(&rec.mOrder), sizeof(rec.mOrder)); 00725 assert(sizeof(rec.mOrder) == 2); 00726 } 00727 else 00728 { 00729 // unknown version 00730 ErrLog( <<"Data in filter database with unknown version " << version ); 00731 ErrLog( <<"record size is " << data.size() ); 00732 } 00733 00734 return rec; 00735 } 00736 00737 00738 AbstractDb::FilterRecordList 00739 AbstractDb::getAllFilters() 00740 { 00741 AbstractDb::FilterRecordList ret; 00742 00743 AbstractDb::Key key = firstFilterKey(); 00744 while ( !key.empty() ) 00745 { 00746 AbstractDb::FilterRecord rec = getFilter(key); 00747 00748 ret.push_back(rec); 00749 00750 key = nextFilterKey(); 00751 } 00752 00753 return ret; 00754 } 00755 00756 00757 AbstractDb::Key 00758 AbstractDb::firstFilterKey() 00759 { 00760 return dbFirstKey(FilterTable); 00761 } 00762 00763 00764 AbstractDb::Key 00765 AbstractDb::nextFilterKey() 00766 { 00767 return dbNextKey(FilterTable); 00768 } 00769 00770 bool 00771 AbstractDb::addToSilo(const Key& key, const SiloRecord& rec) 00772 { 00773 assert( !key.empty() ); 00774 00775 Data data; 00776 { 00777 oDataStream s(data); 00778 00779 short version=1; 00780 assert(sizeof( version) == 2); 00781 s.write((char*)(&version) , sizeof(version)); 00782 00783 encodeString(s, rec.mDestUri); 00784 encodeString(s, rec.mSourceUri); 00785 s.write((char*)(&rec.mOriginalSentTime), sizeof (rec.mOriginalSentTime)); 00786 assert(sizeof(rec.mOriginalSentTime) == 8); 00787 encodeString(s, rec.mTid); 00788 encodeString(s, rec.mMimeType); 00789 encodeString(s, rec.mMessageBody); 00790 00791 s.flush(); 00792 } 00793 return dbWriteRecord(SiloTable, key, data); 00794 } 00795 00796 void 00797 AbstractDb::decodeSiloRecord(Data& data, SiloRecord& rec) 00798 { 00799 iDataStream s(data); 00800 00801 short version; 00802 assert(sizeof(version) == 2); 00803 s.read((char*)(&version), sizeof(version)); 00804 00805 if (version == 1) 00806 { 00807 decodeString(s, rec.mDestUri); 00808 decodeString(s, rec.mSourceUri); 00809 s.read((char*)(&rec.mOriginalSentTime), sizeof(rec.mOriginalSentTime)); 00810 assert(sizeof(rec.mOriginalSentTime) == 8); 00811 decodeString(s, rec.mTid); 00812 decodeString(s, rec.mMimeType); 00813 decodeString(s, rec.mMessageBody); 00814 } 00815 else 00816 { 00817 // unknown version 00818 ErrLog( <<"Data in silo database with unknown version " << version ); 00819 ErrLog( <<"record size is " << data.size() ); 00820 } 00821 } 00822 00823 bool 00824 AbstractDb::getSiloRecords(const Key& skey, AbstractDb::SiloRecordList& recordList) 00825 { 00826 AbstractDb::SiloRecord rec; 00827 00828 Data data; 00829 bool moreRecords = dbFirstRecord(SiloTable, skey, data, false /* forUpdate? */); 00830 if(moreRecords) 00831 { 00832 // Decode and store data 00833 decodeSiloRecord(data,rec); 00834 recordList.push_back(rec); 00835 while((moreRecords = dbNextRecord(SiloTable, skey, data, false /* forUpdate? */))) 00836 { 00837 // Decode and store data 00838 decodeSiloRecord(data,rec); 00839 recordList.push_back(rec); 00840 } 00841 } 00842 00843 return true; 00844 } 00845 00846 void 00847 AbstractDb::eraseSiloRecord(const Key& key) 00848 { 00849 dbEraseRecord(SiloTable, key); 00850 } 00851 00852 void 00853 AbstractDb::cleanupExpiredSiloRecords(UInt64 now, unsigned long expirationTime) 00854 { 00855 AbstractDb::Key key = dbFirstKey(SiloTable); // Iterate on primary key 00856 // Iterate through all silo records - retrieve Original send time embedded into the 00857 // primary key and see if the record has expired. 00858 Data originalSendTimeData; 00859 UInt64 originalSendTime; 00860 while(!key.empty()) 00861 { 00862 ParseBuffer pb(key); 00863 const char* anchor = pb.position(); 00864 pb.skipToChar(':'); 00865 pb.data(originalSendTimeData, anchor); 00866 originalSendTime = originalSendTimeData.convertUInt64(); 00867 if((unsigned long)(now - originalSendTime) > expirationTime) 00868 { 00869 eraseSiloRecord(key); 00870 } 00871 key = dbNextKey(SiloTable); 00872 } 00873 } 00874 00875 /* ==================================================================== 00876 * The Vovida Software License, Version 1.0 00877 * 00878 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00879 * 00880 * Redistribution and use in source and binary forms, with or without 00881 * modification, are permitted provided that the following conditions 00882 * are met: 00883 * 00884 * 1. Redistributions of source code must retain the above copyright 00885 * notice, this list of conditions and the following disclaimer. 00886 * 00887 * 2. Redistributions in binary form must reproduce the above copyright 00888 * notice, this list of conditions and the following disclaimer in 00889 * the documentation and/or other materials provided with the 00890 * distribution. 00891 * 00892 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00893 * and "Vovida Open Communication Application Library (VOCAL)" must 00894 * not be used to endorse or promote products derived from this 00895 * software without prior written permission. For written 00896 * permission, please contact vocal@vovida.org. 00897 * 00898 * 4. Products derived from this software may not be called "VOCAL", nor 00899 * may "VOCAL" appear in their name, without prior written 00900 * permission of Vovida Networks, Inc. 00901 * 00902 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00903 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00904 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00905 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00906 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00907 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00908 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00909 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00910 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00911 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00912 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00913 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00914 * DAMAGE. 00915 * 00916 * ==================================================================== 00917 */
1.7.5.1