2
* Copyright (C) 2010 Djellel Eddine Difallah
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
8
* * Redistributions of source code must retain the above copyright notice,
9
* this list of conditions and the following disclaimer.
10
* * Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
12
* and/or other materials provided with the distribution.
13
* * Neither the name of Djellel Eddine Difallah nor the names of its contributors
14
* may be used to endorse or promote products derived from this software
15
* without specific prior written permission.
17
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27
* THE POSSIBILITY OF SUCH DAMAGE.
31
#include "invalidator.h"
32
#include "query_cache_service.h"
33
#include "memcached_qc.h"
35
#include <drizzled/session.h>
36
#include <drizzled/message/transaction.pb.h>
37
#include <drizzled/message/table.pb.h>
38
#include <drizzled/message/statement_transform.h>
45
using namespace drizzled;
48
Invalidator::Invalidator(string name_arg)
50
plugin::TransactionApplier(name_arg)
54
plugin::ReplicationReturnCode
55
Invalidator::apply(Session &in_session,
56
const message::Transaction &to_apply)
62
size_t stmt_size= to_apply.statement_size();
64
for (size_t i= 0; i < stmt_size; i++)
68
const message::Statement &stmt= to_apply.statement(i);
71
* We don't handle raw SQL for now.
73
if (stmt.type() != message::Statement::RAW_SQL)
75
parseStatementTableMetadata(stmt, schema_name, table_name);
79
continue; /* go on to the next statement */
82
/* Now lets invalidate all the entries of the table */
83
invalidateByTableName(schema_name, table_name);
85
return plugin::SUCCESS;
88
void Invalidator::parseStatementTableMetadata(const message::Statement &in_statement,
89
string &in_schema_name,
90
string &in_table_name) const
92
switch (in_statement.type())
94
case message::Statement::INSERT:
96
const message::TableMetadata &metadata= in_statement.insert_header().table_metadata();
97
in_schema_name.assign(metadata.schema_name());
98
in_table_name.assign(metadata.table_name());
101
case message::Statement::UPDATE:
103
const message::TableMetadata &metadata= in_statement.update_header().table_metadata();
104
in_schema_name.assign(metadata.schema_name());
105
in_table_name.assign(metadata.table_name());
108
case message::Statement::DELETE:
110
const message::TableMetadata &metadata= in_statement.delete_header().table_metadata();
111
in_schema_name.assign(metadata.schema_name());
112
in_table_name.assign(metadata.table_name());
115
case message::Statement::CREATE_SCHEMA:
117
in_schema_name.assign(in_statement.create_schema_statement().schema().name());
118
in_table_name.clear();
121
case message::Statement::ALTER_SCHEMA:
123
in_schema_name.assign(in_statement.alter_schema_statement().after().name());
124
in_table_name.clear();
127
case message::Statement::DROP_SCHEMA:
129
in_schema_name.assign(in_statement.drop_schema_statement().schema_name());
130
in_table_name.clear();
133
case message::Statement::CREATE_TABLE:
135
in_schema_name.assign(in_statement.create_table_statement().table().schema());
136
in_table_name.assign(in_statement.create_table_statement().table().name());
139
case message::Statement::ALTER_TABLE:
141
in_schema_name.assign(in_statement.alter_table_statement().before().schema());
142
in_table_name.assign(in_statement.alter_table_statement().before().name());
145
case message::Statement::DROP_TABLE:
147
const message::TableMetadata &metadata= in_statement.drop_table_statement().table_metadata();
148
in_schema_name.assign(metadata.schema_name());
149
in_table_name.assign(metadata.table_name());
154
/* All other types have no schema and table information */
155
in_schema_name.clear();
156
in_table_name.clear();
161
void Invalidator::invalidateByTableName(const std::string &in_schema_name,
162
const std::string &in_table_name) const
164
/* Reconstitute the schema+table key */
165
string key= in_schema_name+in_table_name;
167
/* Lookup for the invalidated table in the cached tables map */
168
QueryCacheService::CachedTablesEntries::iterator itt= QueryCacheService::cachedTables.find(key);
169
if (itt != QueryCacheService::cachedTables.end())
171
/* Extract the invloved hashes from the map and lookup the local Cache*/
172
QueryCacheService::CachedTablesEntry &entry= *itt;
173
vector<string>::iterator hash;
174
for(hash= entry.second.begin(); hash != entry.second.end(); hash++)
176
QueryCacheService::CacheEntries::iterator it= QueryCacheService::cache.find(*hash);
177
if (it != QueryCacheService::cache.end())
179
/* Remove the Query from the local Cache */
180
QueryCacheService::cache.erase(*hash);
181
/* Remove the Query from Memcached immediatly */
182
MemcachedQueryCache::getClient()->remove(*hash, 0);
185
/* finaly remove the table from the cached table list */
186
QueryCacheService::cachedTables.erase(key);