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 #include <config.h>
00031 #include "invalidator.h"
00032 #include "query_cache_service.h"
00033 #include "memcached_qc.h"
00034
00035 #include <drizzled/session.h>
00036 #include <drizzled/message/transaction.pb.h>
00037 #include <drizzled/message/table.pb.h>
00038 #include <drizzled/message/statement_transform.h>
00039
00040 #include <vector>
00041 #include <string>
00042 #include <algorithm>
00043
00044
00045 using namespace drizzled;
00046 using namespace std;
00047
00048 Invalidator::Invalidator(string name_arg)
00049 :
00050 plugin::TransactionApplier(name_arg)
00051 {
00052 }
00053
00054 plugin::ReplicationReturnCode
00055 Invalidator::apply(Session &in_session,
00056 const message::Transaction &to_apply)
00057 {
00058 (void) in_session;
00059 string schema_name;
00060 string table_name;
00061
00062 size_t stmt_size= to_apply.statement_size();
00063
00064 for (size_t i= 0; i < stmt_size; i++)
00065 {
00066 schema_name.clear();
00067 table_name.clear();
00068 const message::Statement &stmt= to_apply.statement(i);
00069
00070
00071
00072
00073 if (stmt.type() != message::Statement::RAW_SQL)
00074 {
00075 parseStatementTableMetadata(stmt, schema_name, table_name);
00076 }
00077 else
00078 {
00079 continue;
00080 }
00081
00082
00083 invalidateByTableName(schema_name, table_name);
00084 }
00085 return plugin::SUCCESS;
00086 }
00087
00088 void Invalidator::parseStatementTableMetadata(const message::Statement &in_statement,
00089 string &in_schema_name,
00090 string &in_table_name) const
00091 {
00092 switch (in_statement.type())
00093 {
00094 case message::Statement::INSERT:
00095 {
00096 const message::TableMetadata &metadata= in_statement.insert_header().table_metadata();
00097 in_schema_name.assign(metadata.schema_name());
00098 in_table_name.assign(metadata.table_name());
00099 break;
00100 }
00101 case message::Statement::UPDATE:
00102 {
00103 const message::TableMetadata &metadata= in_statement.update_header().table_metadata();
00104 in_schema_name.assign(metadata.schema_name());
00105 in_table_name.assign(metadata.table_name());
00106 break;
00107 }
00108 case message::Statement::DELETE:
00109 {
00110 const message::TableMetadata &metadata= in_statement.delete_header().table_metadata();
00111 in_schema_name.assign(metadata.schema_name());
00112 in_table_name.assign(metadata.table_name());
00113 break;
00114 }
00115 case message::Statement::CREATE_SCHEMA:
00116 {
00117 in_schema_name.assign(in_statement.create_schema_statement().schema().name());
00118 in_table_name.clear();
00119 break;
00120 }
00121 case message::Statement::ALTER_SCHEMA:
00122 {
00123 in_schema_name.assign(in_statement.alter_schema_statement().after().name());
00124 in_table_name.clear();
00125 break;
00126 }
00127 case message::Statement::DROP_SCHEMA:
00128 {
00129 in_schema_name.assign(in_statement.drop_schema_statement().schema_name());
00130 in_table_name.clear();
00131 break;
00132 }
00133 case message::Statement::CREATE_TABLE:
00134 {
00135 in_schema_name.assign(in_statement.create_table_statement().table().schema());
00136 in_table_name.assign(in_statement.create_table_statement().table().name());
00137 break;
00138 }
00139 case message::Statement::ALTER_TABLE:
00140 {
00141 in_schema_name.assign(in_statement.alter_table_statement().before().schema());
00142 in_table_name.assign(in_statement.alter_table_statement().before().name());
00143 break;
00144 }
00145 case message::Statement::DROP_TABLE:
00146 {
00147 const message::TableMetadata &metadata= in_statement.drop_table_statement().table_metadata();
00148 in_schema_name.assign(metadata.schema_name());
00149 in_table_name.assign(metadata.table_name());
00150 break;
00151 }
00152 default:
00153 {
00154
00155 in_schema_name.clear();
00156 in_table_name.clear();
00157 break;
00158 }
00159 }
00160 }
00161 void Invalidator::invalidateByTableName(const std::string &in_schema_name,
00162 const std::string &in_table_name) const
00163 {
00164
00165 string key= in_schema_name+in_table_name;
00166
00167
00168 QueryCacheService::CachedTablesEntries::iterator itt= QueryCacheService::cachedTables.find(key);
00169 if (itt != QueryCacheService::cachedTables.end())
00170 {
00171
00172 QueryCacheService::CachedTablesEntry &entry= *itt;
00173 vector<string>::iterator hash;
00174 for(hash= entry.second.begin(); hash != entry.second.end(); hash++)
00175 {
00176 QueryCacheService::CacheEntries::iterator it= QueryCacheService::cache.find(*hash);
00177 if (it != QueryCacheService::cache.end())
00178 {
00179
00180 QueryCacheService::cache.erase(*hash);
00181
00182 MemcachedQueryCache::getClient()->remove(*hash, 0);
00183 }
00184 }
00185
00186 QueryCacheService::cachedTables.erase(key);
00187 }
00188 }