12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
18
#include <drizzled/error.h>
19
#include <drizzled/global_charset_info.h>
20
#include <drizzled/internal/m_string.h>
21
#include <drizzled/internal/my_pthread.h>
22
#include <drizzled/message/table.h>
23
#include <drizzled/plugin/storage_engine.h>
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include <drizzled/server_includes.h>
24
17
#include <drizzled/table.h>
27
18
#include "ha_blackhole.h"
35
#include <google/protobuf/io/zero_copy_stream.h>
36
#include <google/protobuf/io/zero_copy_stream_impl.h>
39
22
using namespace std;
40
using namespace google;
41
using namespace drizzled;
43
#define BLACKHOLE_EXT ".blk"
45
static pthread_mutex_t blackhole_mutex;
24
static const string engine_name("BLACKHOLE");
48
27
static const char *ha_blackhole_exts[] = {
53
31
class BlackholeEngine : public drizzled::plugin::StorageEngine
55
typedef std::map<std::string, BlackholeShare*> BlackholeMap;
56
BlackholeMap blackhole_open_tables;
59
34
BlackholeEngine(const string &name_arg)
60
: drizzled::plugin::StorageEngine(name_arg,
62
HTON_CAN_INDEX_BLOBS |
63
HTON_SKIP_STORE_LOCK |
65
blackhole_open_tables()
67
table_definition_ext= BLACKHOLE_EXT;
70
virtual ~BlackholeEngine()
72
pthread_mutex_destroy(&blackhole_mutex);
75
virtual Cursor *create(Table &table)
77
return new ha_blackhole(*this, table);
35
: drizzled::plugin::StorageEngine(name_arg, HTON_FILE_BASED | HTON_CAN_RECREATE) {}
36
virtual Cursor *create(TableShare *table,
39
return new (mem_root) ha_blackhole(this, table);
80
42
const char **bas_ext() const {
81
43
return ha_blackhole_exts;
84
int doCreateTable(Session&,
86
const drizzled::identifier::Table &identifier,
87
drizzled::message::Table&);
89
int doDropTable(Session&, const drizzled::identifier::Table &identifier);
91
BlackholeShare *findOpenTable(const string table_name);
92
void addOpenTable(const string &table_name, BlackholeShare *);
93
void deleteOpenTable(const string &table_name);
95
int doGetTableDefinition(Session& session,
96
const drizzled::identifier::Table &identifier,
97
drizzled::message::Table &table_message);
99
/* The following defines can be increased if necessary */
100
uint32_t max_supported_keys() const { return BLACKHOLE_MAX_KEY; }
101
uint32_t max_supported_key_length() const { return BLACKHOLE_MAX_KEY_LENGTH; }
102
uint32_t max_supported_key_part_length() const { return BLACKHOLE_MAX_KEY_LENGTH; }
104
uint32_t index_flags(enum ha_key_alg) const
106
return (HA_READ_NEXT |
113
bool doDoesTableExist(Session& session, const drizzled::identifier::Table &identifier);
114
int doRenameTable(Session&, const drizzled::identifier::Table &from, const drizzled::identifier::Table &to);
115
void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
116
const drizzled::identifier::Schema &schema_identifier,
117
drizzled::identifier::Table::vector &set_of_identifiers);
46
int createTableImplementation(Session*, const char *, Table *,
47
HA_CREATE_INFO *, drizzled::message::Table*);
49
int deleteTableImplementation(Session*, const string table_name);
121
void BlackholeEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
122
const drizzled::identifier::Schema &schema_identifier,
123
drizzled::identifier::Table::vector &set_of_identifiers)
125
drizzled::CachedDirectory::Entries entries= directory.getEntries();
127
for (drizzled::CachedDirectory::Entries::iterator entry_iter= entries.begin();
128
entry_iter != entries.end(); ++entry_iter)
130
drizzled::CachedDirectory::Entry *entry= *entry_iter;
131
const string *filename= &entry->filename;
133
assert(filename->size());
135
const char *ext= strchr(filename->c_str(), '.');
137
if (ext == NULL || my_strcasecmp(system_charset_info, ext, BLACKHOLE_EXT) ||
138
(filename->compare(0, strlen(TMP_FILE_PREFIX), TMP_FILE_PREFIX) == 0))
142
char uname[NAME_LEN + 1];
143
uint32_t file_name_len;
145
file_name_len= identifier::Table::filename_to_tablename(filename->c_str(), uname, sizeof(uname));
146
// TODO: Remove need for memory copy here
147
uname[file_name_len - sizeof(BLACKHOLE_EXT) + 1]= '\0'; // Subtract ending, place NULL
149
set_of_identifiers.push_back(identifier::Table(schema_identifier, uname));
154
int BlackholeEngine::doRenameTable(Session&, const drizzled::identifier::Table &from, const drizzled::identifier::Table &to)
158
for (const char **ext= bas_ext(); *ext ; ext++)
160
if (rename_file_ext(from.getPath().c_str(), to.getPath().c_str(), *ext))
162
if ((error=errno) != ENOENT)
170
BlackholeShare *BlackholeEngine::findOpenTable(const string table_name)
172
BlackholeMap::iterator find_iter=
173
blackhole_open_tables.find(table_name);
175
if (find_iter != blackhole_open_tables.end())
176
return (*find_iter).second;
181
void BlackholeEngine::addOpenTable(const string &table_name, BlackholeShare *share)
183
blackhole_open_tables[table_name]= share;
186
void BlackholeEngine::deleteOpenTable(const string &table_name)
188
blackhole_open_tables.erase(table_name);
52
/* Static declarations for shared structures */
54
static pthread_mutex_t blackhole_mutex;
55
static HASH blackhole_open_tables;
57
static st_blackhole_share *get_share(const char *table_name);
58
static void free_share(st_blackhole_share *share);
193
60
/*****************************************************************************
194
61
** BLACKHOLE tables
195
62
*****************************************************************************/
197
ha_blackhole::ha_blackhole(drizzled::plugin::StorageEngine &engine_arg,
199
:Cursor(engine_arg, table_arg), share(NULL)
64
ha_blackhole::ha_blackhole(drizzled::plugin::StorageEngine *engine_arg,
65
TableShare *table_arg)
66
:Cursor(engine_arg, table_arg)
69
uint32_t ha_blackhole::index_flags(uint32_t inx, uint32_t, bool) const
71
return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
72
0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
73
HA_READ_ORDER | HA_KEYREAD_ONLY);
202
76
int ha_blackhole::open(const char *name, int, uint32_t)
204
78
if (!(share= get_share(name)))
205
79
return(HA_ERR_OUT_OF_MEM);
207
lock.init(&share->lock);
81
thr_lock_data_init(&share->lock, &lock, NULL);
211
85
int ha_blackhole::close(void)
217
int BlackholeEngine::doCreateTable(Session&,
219
const drizzled::identifier::Table &identifier,
220
drizzled::message::Table& proto)
222
string serialized_proto;
225
new_path= identifier.getPath();
226
new_path+= BLACKHOLE_EXT;
227
fstream output(new_path.c_str(), ios::out | ios::binary);
233
if (! proto.SerializeToOstream(&output))
236
unlink(new_path.c_str());
244
int BlackholeEngine::doDropTable(Session&,
245
const drizzled::identifier::Table &identifier)
247
string new_path(identifier.getPath());
249
new_path+= BLACKHOLE_EXT;
251
int error= unlink(new_path.c_str());
262
bool BlackholeEngine::doDoesTableExist(Session&,
263
const drizzled::identifier::Table &identifier)
265
string proto_path(identifier.getPath());
266
proto_path.append(BLACKHOLE_EXT);
268
if (access(proto_path.c_str(), F_OK))
277
int BlackholeEngine::doGetTableDefinition(Session&,
278
const drizzled::identifier::Table &identifier,
279
drizzled::message::Table &table_proto)
283
new_path= identifier.getPath();
284
new_path+= BLACKHOLE_EXT;
286
int fd= open(new_path.c_str(), O_RDONLY);
91
int BlackholeEngine::createTableImplementation(Session*, const char *path,
92
Table *, HA_CREATE_INFO *,
93
drizzled::message::Table*)
95
FILE *blackhole_table;
97
/* Create an empty file for the Drizzle core to track whether
98
a blackhole table exists */
99
if ((blackhole_table= fopen(path, "w")) == NULL)
102
/* This file should never have to be reopened */
103
fclose(blackhole_table);
108
int BlackholeEngine::deleteTableImplementation(Session*, const string path)
110
if (unlink(path.c_str()) != 0)
293
google::protobuf::io::ZeroCopyInputStream* input=
294
new google::protobuf::io::FileInputStream(fd);
297
return HA_ERR_CRASHED_ON_USAGE;
299
if (not table_proto.ParseFromZeroCopyStream(input))
303
if (not table_proto.IsInitialized())
305
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
306
table_proto.name().empty() ? " " : table_proto.name().c_str(),
307
table_proto.InitializationErrorString().c_str());
309
return ER_CORRUPT_TABLE_DEFINITION;
312
return HA_ERR_CRASHED_ON_USAGE;
320
118
const char *ha_blackhole::index_type(uint32_t)
409
BlackholeShare *ha_blackhole::get_share(const char *table_name)
241
static st_blackhole_share *get_share(const char *table_name)
243
st_blackhole_share *share;
246
length= (uint) strlen(table_name);
411
247
pthread_mutex_lock(&blackhole_mutex);
413
BlackholeEngine *a_engine= static_cast<BlackholeEngine *>(getEngine());
414
share= a_engine->findOpenTable(table_name);
249
if (!(share= (st_blackhole_share*) hash_search(&blackhole_open_tables,
250
(unsigned char*) table_name, length)))
418
share= new (nothrow) BlackholeShare(table_name);
252
if (!(share= (st_blackhole_share*) malloc(sizeof(st_blackhole_share) +
255
memset(share, 0, sizeof(st_blackhole_share) + length);
257
share->table_name_length= length;
258
strcpy(share->table_name, table_name);
260
if (my_hash_insert(&blackhole_open_tables, (unsigned char*) share))
421
pthread_mutex_unlock(&blackhole_mutex);
262
free((unsigned char*) share);
425
a_engine->addOpenTable(share->table_name, share);
267
thr_lock_init(&share->lock);
427
269
share->use_count++;
428
272
pthread_mutex_unlock(&blackhole_mutex);
433
void ha_blackhole::free_share()
276
static void free_share(st_blackhole_share *share)
435
278
pthread_mutex_lock(&blackhole_mutex);
436
279
if (!--share->use_count)
438
BlackholeEngine *a_engine= static_cast<BlackholeEngine *>(getEngine());
439
a_engine->deleteOpenTable(share->table_name);
280
hash_delete(&blackhole_open_tables, (unsigned char*) share);
442
281
pthread_mutex_unlock(&blackhole_mutex);
445
BlackholeShare::BlackholeShare(const string table_name_arg)
446
: use_count(0), table_name(table_name_arg)
448
thr_lock_init(&lock);
451
BlackholeShare::~BlackholeShare()
284
static void blackhole_free_key(st_blackhole_share *share)
286
thr_lock_delete(&share->lock);
287
free((unsigned char*) share);
290
static unsigned char* blackhole_get_key(st_blackhole_share *share, size_t *length, bool)
292
*length= share->table_name_length;
293
return (unsigned char*) share->table_name;
457
296
static drizzled::plugin::StorageEngine *blackhole_engine= NULL;
459
static int blackhole_init(drizzled::module::Context &context)
298
static int blackhole_init(drizzled::plugin::Registry ®istry)
462
blackhole_engine= new BlackholeEngine("BLACKHOLE");
463
context.add(blackhole_engine);
301
blackhole_engine= new BlackholeEngine(engine_name);
302
registry.add(blackhole_engine);
465
304
pthread_mutex_init(&blackhole_mutex, MY_MUTEX_INIT_FAST);
471
DRIZZLE_DECLARE_PLUGIN
305
(void) hash_init(&blackhole_open_tables, system_charset_info,32,0,0,
306
(hash_get_key) blackhole_get_key,
307
(hash_free_key) blackhole_free_key, 0);
312
static int blackhole_fini(drizzled::plugin::Registry ®istry)
314
registry.remove(blackhole_engine);
315
delete blackhole_engine;
317
hash_free(&blackhole_open_tables);
318
pthread_mutex_destroy(&blackhole_mutex);
323
drizzle_declare_plugin(blackhole)
477
328
"/dev/null storage engine (anything you write to it disappears)",
478
329
PLUGIN_LICENSE_GPL,
479
330
blackhole_init, /* Plugin Init */
331
blackhole_fini, /* Plugin Deinit */
332
NULL, /* status variables */
333
NULL, /* system variables */
481
334
NULL /* config options */
483
DRIZZLE_DECLARE_PLUGIN_END;
336
drizzle_declare_plugin_end;