00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <iostream>
00021 #include <syslog.h>
00022 #include <string.h>
00023 #include <algorithm>
00024 #include <cctype>
00025 #include "wlcacheddb.h"
00026 #include "dbdefs.h"
00027 #include "pmatcher.h"
00028
00029 using namespace std;
00030
00031 #define WLCACHEDDBDBG false
00032 #define WLCACHEDMATCHDBG false
00033
00034 WlCachedDB::WlCachedDB(class DB& db,
00035 bool initmode,
00036 const WLStaticDef& staticDef) throw(std::exception)
00037 : _db(db),
00038 _staticDef(staticDef)
00039 {
00040 if(initmode) {
00041 _db.createTable(_staticDef);
00042 }
00043 dbi_result result = _db.executeSQL(_staticDef._testTable);
00044 if(!result)
00045 return;
00046
00047 unsigned numrows = dbi_result_get_numrows(result);
00048 if(numrows == 0) {
00049 dbi_result_free(result);
00050 return;
00051 }
00052 dbi_result_next_row(result);
00053 unsigned numfields = dbi_result_get_numfields(result);
00054 if(WLCACHEDDBDBG)
00055 cout << "numfields: " << numfields << endl;
00056 unsigned primaryIdx = numfields;
00057 for(unsigned i=0;i < numfields;i++) {
00058 const char* colname = dbi_result_get_field_name(result,i+1);
00059 if(WLCACHEDDBDBG)
00060 cout << i << ": " << colname << endl;
00061 if(strcmp(colname,_staticDef._primaryKey) == 0)
00062 primaryIdx = i;
00063 else
00064 _heading.insert(Heading::value_type(colname,i));
00065 }
00066 if(primaryIdx >= numfields) {
00067 dbi_result_free(result);
00068 throw runtime_error(string("WlCachedDb no primary idx in table ")+_staticDef._tableName);
00069 }
00070 for(unsigned i=0;i < numrows;i++) {
00071 string lowerKey( dbi_result_get_string_idx(result,primaryIdx+1) );
00072 transform( lowerKey.begin(), lowerKey.end(), lowerKey.begin(), ToLower());
00073 if(WLCACHEDDBDBG)
00074 cout << "row: " << i << " key: " << lowerKey << endl;
00075 Entry row;
00076 for(Heading::const_iterator itr=_heading.begin();itr != _heading.end();++itr) {
00077 string lowerVal;
00078 const char *val = dbi_result_get_string_idx(result,itr->second+1);
00079 if(val)
00080 lowerVal = val;
00081 else
00082 lowerVal = "";
00083 transform( lowerVal.begin(), lowerVal.end(), lowerVal.begin(), ToLower());
00084 if(WLCACHEDDBDBG)
00085 cout << "idx: " << itr->second << " val: " << val << endl;
00086 row.insert(Entry::value_type(itr->second,lowerVal));
00087 }
00088 _data.insert(Data::value_type("'"+lowerKey+"'",row));
00089 if(dbi_result_next_row(result) == 0)
00090 break;
00091 }
00092 dbi_result_free(result);
00093 }
00094 bool WlCachedDB::check(const class Triplet& triplet) throw(std::exception)
00095 {
00096 switch(_staticDef._compareMode) {
00097 case WlModule::CM_exactMatch:
00098 return exactMatch( "wl", triplet );
00099 case WlModule::CM_patternMatch:
00100 return patternMatch( "wl", triplet );
00101 default:
00102 return false;
00103 }
00104 }
00105 bool WlCachedDB::exactMatch(const std::string logprefix,const class Triplet& triplet)
00106 {
00107
00108
00109 string searchfor = triplet.getMember(_staticDef._compares[0]._tripletMember);
00110 transform( searchfor.begin(), searchfor.end(), searchfor.begin(), ToLower());
00111 if(WLCACHEDMATCHDBG)
00112 cout << "exactMatch: " << searchfor << endl;
00113
00114 Data::const_iterator itr = _data.find(searchfor);
00115
00116 if( itr == _data.end() ) {
00117 return false;
00118
00119
00120
00121
00122
00123
00124
00125 }
00126 logMatch(logprefix,itr,triplet);
00127 return true;
00128 }
00129
00130 bool WlCachedDB::patternMatch(const std::string logprefix,const class Triplet& triplet)
00131 {
00132 std::string pattern;
00133 try {
00134 PatternMatcher pmatcher(triplet);
00135 for(Data::const_iterator itr=_data.begin();itr != _data.end();++itr) {
00136
00137 pattern = itr->first.substr(1,itr->first.size()-2);
00138
00139 if( pmatcher.match(pattern) ) {
00140
00141 logMatch(logprefix,itr,triplet);
00142 return true;
00143 }
00144 }
00145 } catch(exception &e) {
00146 syslog(LOG_ERR,"pattern match failed: '%s' in pattern: %s",
00147 e.what(),pattern.c_str());
00148 }
00149 return false;
00150 }
00151 void WlCachedDB::logMatch(const std::string& logprefix,Data::const_iterator& itr,const Triplet& triplet) const
00152 {
00153 string strComment = getRowComment(itr);
00154 syslog(LOG_INFO,"%s %s: %s -> %s, %s: %s",
00155 logprefix.c_str(),_staticDef._tableName,triplet.getSender().c_str(),
00156 triplet.getRecipient().c_str(),triplet.getClientAddress().c_str(),strComment.c_str());
00157 }
00158
00159 string WlCachedDB::getRowComment(Data::const_iterator& itr) const
00160 {
00161 string strComment;
00162 Heading::const_iterator cmtitr=_heading.find(_staticDef._commentField);
00163 if( cmtitr == _heading.end() ) {
00164 strComment = "(comment field not found in table definition, field: "
00165 + string(_staticDef._commentField) + ")";
00166 } else {
00167 Entry::const_iterator eitr = itr->second.find(cmtitr->second);
00168 if(eitr == itr->second.end())
00169 strComment = "(comment not found in row)";
00170 else
00171 strComment = eitr->second;
00172 }
00173 return strComment;
00174 }
00175 WlCachedDB::~WlCachedDB()
00176 {
00177 }
00178
00179