~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/storage_engine.h

Merged in latest plugin-slot-reorg.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
#ifndef DRIZZLED_PLUGIN_STORAGE_ENGINE_H
 
21
#define DRIZZLED_PLUGIN_STORAGE_ENGINE_H
 
22
 
 
23
 
 
24
#include <drizzled/definitions.h>
 
25
#include <drizzled/plugin.h>
 
26
#include <drizzled/handler_structs.h>
 
27
#include <drizzled/message/table.pb.h>
 
28
#include "drizzled/plugin/plugin.h"
 
29
#include <drizzled/registry.h>
 
30
 
 
31
#include <bitset>
 
32
#include <string>
 
33
#include <vector>
 
34
 
 
35
class TableList;
 
36
class Session;
 
37
class XID;
 
38
class handler;
 
39
 
 
40
class TableShare;
 
41
typedef struct st_mysql_lex_string LEX_STRING;
 
42
typedef bool (stat_print_fn)(Session *session, const char *type, uint32_t type_len,
 
43
                             const char *file, uint32_t file_len,
 
44
                             const char *status, uint32_t status_len);
 
45
 
 
46
/* Possible flags of a StorageEngine (there can be 32 of them) */
 
47
enum engine_flag_bits {
 
48
  HTON_BIT_ALTER_NOT_SUPPORTED,       // Engine does not support alter
 
49
  HTON_BIT_CAN_RECREATE,              // Delete all is used for truncate
 
50
  HTON_BIT_HIDDEN,                    // Engine does not appear in lists
 
51
  HTON_BIT_FLUSH_AFTER_RENAME,
 
52
  HTON_BIT_NOT_USER_SELECTABLE,
 
53
  HTON_BIT_TEMPORARY_NOT_SUPPORTED,   // Having temporary tables not supported
 
54
  HTON_BIT_TEMPORARY_ONLY,
 
55
  HTON_BIT_FILE_BASED, // use for check_lowercase_names
 
56
  HTON_BIT_HAS_DATA_DICTIONARY,
 
57
  HTON_BIT_SIZE
 
58
};
 
59
 
 
60
static const std::bitset<HTON_BIT_SIZE> HTON_NO_FLAGS(0);
 
61
static const std::bitset<HTON_BIT_SIZE> HTON_ALTER_NOT_SUPPORTED(1 << HTON_BIT_ALTER_NOT_SUPPORTED);
 
62
static const std::bitset<HTON_BIT_SIZE> HTON_CAN_RECREATE(1 << HTON_BIT_CAN_RECREATE);
 
63
static const std::bitset<HTON_BIT_SIZE> HTON_HIDDEN(1 << HTON_BIT_HIDDEN);
 
64
static const std::bitset<HTON_BIT_SIZE> HTON_FLUSH_AFTER_RENAME(1 << HTON_BIT_FLUSH_AFTER_RENAME);
 
65
static const std::bitset<HTON_BIT_SIZE> HTON_NOT_USER_SELECTABLE(1 << HTON_BIT_NOT_USER_SELECTABLE);
 
66
static const std::bitset<HTON_BIT_SIZE> HTON_TEMPORARY_NOT_SUPPORTED(1 << HTON_BIT_TEMPORARY_NOT_SUPPORTED);
 
67
static const std::bitset<HTON_BIT_SIZE> HTON_TEMPORARY_ONLY(1 << HTON_BIT_TEMPORARY_ONLY);
 
68
static const std::bitset<HTON_BIT_SIZE> HTON_FILE_BASED(1 << HTON_BIT_FILE_BASED);
 
69
static const std::bitset<HTON_BIT_SIZE> HTON_HAS_DATA_DICTIONARY(1 << HTON_BIT_HAS_DATA_DICTIONARY);
 
70
 
 
71
class Table;
 
72
 
 
73
namespace drizzled
 
74
{
 
75
namespace plugin
 
76
{
 
77
 
 
78
const std::string UNKNOWN_STRING("UNKNOWN");
 
79
 
 
80
class TableNameIteratorImplementation;
 
81
/*
 
82
  StorageEngine is a singleton structure - one instance per storage engine -
 
83
  to provide access to storage engine functionality that works on the
 
84
  "global" level (unlike handler class that works on a per-table basis)
 
85
 
 
86
  usually StorageEngine instance is defined statically in ha_xxx.cc as
 
87
 
 
88
  static StorageEngine { ... } xxx_engine;
 
89
 
 
90
  savepoint_*, prepare, recover, and *_by_xid pointers can be 0.
 
91
*/
 
92
class StorageEngine : public Plugin
 
93
{
 
94
  /*
 
95
    Name used for storage engine.
 
96
  */
 
97
  const bool two_phase_commit;
 
98
  bool enabled;
 
99
 
 
100
  const std::bitset<HTON_BIT_SIZE> flags; /* global handler flags */
 
101
  /*
 
102
    to store per-savepoint data storage engine is provided with an area
 
103
    of a requested size (0 is ok here).
 
104
    savepoint_offset must be initialized statically to the size of
 
105
    the needed memory to store per-savepoint information.
 
106
    After xxx_init it is changed to be an offset to savepoint storage
 
107
    area and need not be used by storage engine.
 
108
    see binlog_engine and binlog_savepoint_set/rollback for an example.
 
109
  */
 
110
  size_t savepoint_offset;
 
111
  size_t orig_savepoint_offset;
 
112
  std::vector<std::string> aliases;
 
113
 
 
114
  void setTransactionReadWrite(Session* session);
 
115
 
 
116
protected:
 
117
 
 
118
  /**
 
119
   * Implementing classes should override these to provide savepoint
 
120
   * functionality.
 
121
   */
 
122
  virtual int savepoint_set_hook(Session *, void *) { return 0; }
 
123
 
 
124
  virtual int savepoint_rollback_hook(Session *, void *) { return 0; }
 
125
 
 
126
  virtual int savepoint_release_hook(Session *, void *) { return 0; }
 
127
 
 
128
public:
 
129
 
 
130
  StorageEngine(const std::string name_arg,
 
131
                const std::bitset<HTON_BIT_SIZE> &flags_arg= HTON_NO_FLAGS,
 
132
                size_t savepoint_offset_arg= 0,
 
133
                bool support_2pc= false);
 
134
 
 
135
  virtual ~StorageEngine();
 
136
 
 
137
  virtual int getTableProtoImplementation(const char* path,
 
138
                                          drizzled::message::Table *table_proto)
 
139
    {
 
140
      (void)path;
 
141
      (void)table_proto;
 
142
      return ENOENT;
 
143
    }
 
144
 
 
145
  /*
 
146
    each storage engine has it's own memory area (actually a pointer)
 
147
    in the session, for storing per-connection information.
 
148
    It is accessed as
 
149
 
 
150
      session->ha_data[xxx_engine.slot]
 
151
 
 
152
   slot number is initialized by MySQL after xxx_init() is called.
 
153
  */
 
154
  uint32_t slot;
 
155
 
 
156
  inline uint32_t getSlot (void) { return slot; }
 
157
  inline void setSlot (uint32_t value) { slot= value; }
 
158
 
 
159
  const std::vector<std::string>& getAliases()
 
160
  {
 
161
    return aliases;
 
162
  }
 
163
 
 
164
  void addAlias(std::string alias)
 
165
  {
 
166
    aliases.push_back(alias);
 
167
  }
 
168
 
 
169
  bool has_2pc()
 
170
  {
 
171
    return two_phase_commit;
 
172
  }
 
173
 
 
174
 
 
175
  bool is_enabled() const
 
176
  {
 
177
    return enabled;
 
178
  }
 
179
 
 
180
  bool is_user_selectable() const
 
181
  {
 
182
    return not flags.test(HTON_BIT_NOT_USER_SELECTABLE);
 
183
  }
 
184
 
 
185
  bool check_flag(const engine_flag_bits flag) const
 
186
  {
 
187
    return flags.test(flag);
 
188
  }
 
189
 
 
190
  void enable() { enabled= true; }
 
191
  void disable() { enabled= false; }
 
192
 
 
193
  /*
 
194
    StorageEngine methods:
 
195
 
 
196
    close_connection is only called if
 
197
    session->ha_data[xxx_engine.slot] is non-zero, so even if you don't need
 
198
    this storage area - set it to something, so that MySQL would know
 
199
    this storage engine was accessed in this connection
 
200
  */
 
201
  virtual int close_connection(Session  *)
 
202
  {
 
203
    return 0;
 
204
  }
 
205
  /*
 
206
    'all' is true if it's a real commit, that makes persistent changes
 
207
    'all' is false if it's not in fact a commit but an end of the
 
208
    statement that is part of the transaction.
 
209
    NOTE 'all' is also false in auto-commit mode where 'end of statement'
 
210
    and 'real commit' mean the same event.
 
211
  */
 
212
  virtual int  commit(Session *, bool)
 
213
  {
 
214
    return 0;
 
215
  }
 
216
 
 
217
  virtual int  rollback(Session *, bool)
 
218
  {
 
219
    return 0;
 
220
  }
 
221
 
 
222
  /*
 
223
    The void * points to an uninitialized storage area of requested size
 
224
    (see savepoint_offset description)
 
225
  */
 
226
  int savepoint_set(Session *session, void *sp)
 
227
  {
 
228
    return savepoint_set_hook(session, (unsigned char *)sp+savepoint_offset);
 
229
  }
 
230
 
 
231
  /*
 
232
    The void * points to a storage area, that was earlier passed
 
233
    to the savepoint_set call
 
234
  */
 
235
  int savepoint_rollback(Session *session, void *sp)
 
236
  {
 
237
     return savepoint_rollback_hook(session,
 
238
                                    (unsigned char *)sp+savepoint_offset);
 
239
  }
 
240
 
 
241
  int savepoint_release(Session *session, void *sp)
 
242
  {
 
243
    return savepoint_release_hook(session,
 
244
                                  (unsigned char *)sp+savepoint_offset);
 
245
  }
 
246
 
 
247
  virtual int  prepare(Session *, bool) { return 0; }
 
248
  virtual int  recover(XID *, uint32_t) { return 0; }
 
249
  virtual int  commit_by_xid(XID *) { return 0; }
 
250
  virtual int  rollback_by_xid(XID *) { return 0; }
 
251
  virtual handler *create(TableShare *, MEM_ROOT *)= 0;
 
252
  /* args: path */
 
253
  virtual void drop_database(char*) { }
 
254
  virtual int start_consistent_snapshot(Session *) { return 0; }
 
255
  virtual bool flush_logs() { return false; }
 
256
  virtual bool show_status(Session *, stat_print_fn *, enum ha_stat_type)
 
257
  {
 
258
    return false;
 
259
  }
 
260
 
 
261
  /* args: current_session, tables, cond */
 
262
  virtual int fill_files_table(Session *, TableList *,
 
263
                               Item *) { return 0; }
 
264
  virtual int release_temporary_latches(Session *) { return false; }
 
265
 
 
266
  /**
 
267
    If frm_error() is called then we will use this to find out what file
 
268
    extentions exist for the storage engine. This is also used by the default
 
269
    rename_table and delete_table method in handler.cc.
 
270
 
 
271
    For engines that have two file name extentions (separate meta/index file
 
272
    and data file), the order of elements is relevant. First element of engine
 
273
    file name extentions array should be meta/index file extention. Second
 
274
    element - data file extention. This order is assumed by
 
275
    prepare_for_repair() when REPAIR Table ... USE_FRM is issued.
 
276
  */
 
277
  virtual const char **bas_ext() const =0;
 
278
 
 
279
protected:
 
280
  virtual int createTableImplementation(Session *session,
 
281
                                        const char *table_name,
 
282
                                        Table *table_arg,
 
283
                                        HA_CREATE_INFO *create_info,
 
284
                                        drizzled::message::Table* proto)= 0;
 
285
 
 
286
  virtual int renameTableImplementation(Session* session,
 
287
                                        const char *from, const char *to);
 
288
 
 
289
  virtual int deleteTableImplementation(Session* session,
 
290
                                        const std::string table_path);
 
291
 
 
292
public:
 
293
  int createTable(Session *session, const char *path, Table *table_arg,
 
294
                  HA_CREATE_INFO *create_info,
 
295
                  drizzled::message::Table *proto) 
 
296
  {
 
297
    char name_buff[FN_REFLEN];
 
298
    const char *table_name;
 
299
 
 
300
    table_name= checkLowercaseNames(path, name_buff);
 
301
 
 
302
    setTransactionReadWrite(session);
 
303
 
 
304
    return createTableImplementation(session, table_name, table_arg,
 
305
                                     create_info, proto);
 
306
  }
 
307
 
 
308
  int renameTable(Session *session, const char *from, const char *to) 
 
309
  {
 
310
    setTransactionReadWrite(session);
 
311
 
 
312
    return renameTableImplementation(session, from, to);
 
313
  }
 
314
 
 
315
  int deleteTable(Session* session, const std::string table_path) 
 
316
  {
 
317
    setTransactionReadWrite(session);
 
318
 
 
319
    return deleteTableImplementation(session, table_path);
 
320
  }
 
321
 
 
322
  const char *checkLowercaseNames(const char *path, char *tmp_path);
 
323
 
 
324
  virtual TableNameIteratorImplementation* tableNameIterator(const std::string &database)
 
325
  {
 
326
    (void)database;
 
327
    return NULL;
 
328
  }
 
329
 
 
330
 
 
331
  static void add(plugin::StorageEngine *engine);
 
332
  static void remove(plugin::StorageEngine *engine);
 
333
 
 
334
  static int getTableProto(const char* path, message::Table *table_proto);
 
335
 
 
336
  static plugin::StorageEngine *findByName(Session *session,
 
337
                                           std::string find_str);
 
338
  static void closeConnection(Session* session);
 
339
  static void dropDatabase(char* path);
 
340
  static int commitOrRollbackByXID(XID *xid, bool commit);
 
341
  static int releaseTemporaryLatches(Session *session);
 
342
  static bool flushLogs(plugin::StorageEngine *db_type);
 
343
  static int recover(HASH *commit_list);
 
344
  static int startConsistentSnapshot(Session *session);
 
345
  static int deleteTable(Session *session, const char *path, const char *db,
 
346
                         const char *alias, bool generate_warning);
 
347
  static inline const std::string &resolveName(const StorageEngine *engine)
 
348
  {
 
349
    return engine == NULL ? UNKNOWN_STRING : engine->getName();
 
350
  }
 
351
 
 
352
};
 
353
 
 
354
class TableNameIteratorImplementation
 
355
{
 
356
protected:
 
357
  std::string db;
 
358
public:
 
359
  TableNameIteratorImplementation(const std::string &database) : db(database)
 
360
    {};
 
361
  virtual ~TableNameIteratorImplementation() {};
 
362
 
 
363
  virtual int next(std::string *name)= 0;
 
364
 
 
365
};
 
366
 
 
367
class TableNameIterator
 
368
{
 
369
private:
 
370
  ::drizzled::Registry<plugin::StorageEngine *>::iterator engine_iter;
 
371
  plugin::TableNameIteratorImplementation *current_implementation;
 
372
  plugin::TableNameIteratorImplementation *default_implementation;
 
373
  std::string database;
 
374
public:
 
375
  TableNameIterator(const std::string &db);
 
376
  ~TableNameIterator();
 
377
 
 
378
  int next(std::string *name);
 
379
};
 
380
 
 
381
 
 
382
} /* namespace plugin */
 
383
} /* namespace drizzled */
 
384
 
 
385
/* lookups */
 
386
/**
 
387
  Return the default storage engine plugin::StorageEngine for thread
 
388
 
 
389
  @param ha_default_storage_engine(session)
 
390
  @param session         current thread
 
391
 
 
392
  @return
 
393
    pointer to plugin::StorageEngine
 
394
*/
 
395
drizzled::plugin::StorageEngine *ha_default_storage_engine(Session *session);
 
396
 
 
397
handler *get_new_handler(TableShare *share, MEM_ROOT *alloc,
 
398
                         drizzled::plugin::StorageEngine *db_type);
 
399
 
 
400
 
 
401
 
 
402
/** @TODO remove each of the following convenience naming methods */
 
403
 
 
404
static inline void ha_close_connection(Session *session)
 
405
{
 
406
  drizzled::plugin::StorageEngine::closeConnection(session);
 
407
}
 
408
 
 
409
static inline void ha_drop_database(char* path)
 
410
{
 
411
  drizzled::plugin::StorageEngine::dropDatabase(path);
 
412
}
 
413
 
 
414
static inline int ha_commit_or_rollback_by_xid(XID *xid, bool commit)
 
415
{
 
416
  return drizzled::plugin::StorageEngine::commitOrRollbackByXID(xid, commit);
 
417
}
 
418
 
 
419
/* report to InnoDB that control passes to the client */
 
420
static inline int ha_release_temporary_latches(Session *session)
 
421
{
 
422
  return drizzled::plugin::StorageEngine::releaseTemporaryLatches(session);
 
423
}
 
424
 
 
425
static inline bool ha_flush_logs(drizzled::plugin::StorageEngine *engine)
 
426
{
 
427
  return drizzled::plugin::StorageEngine::flushLogs(engine);
 
428
}
 
429
 
 
430
static inline int ha_recover(HASH *commit_list)
 
431
{
 
432
  return drizzled::plugin::StorageEngine::recover(commit_list);
 
433
}
 
434
 
 
435
static inline int ha_start_consistent_snapshot(Session *session)
 
436
{
 
437
  return drizzled::plugin::StorageEngine::startConsistentSnapshot(session);
 
438
}
 
439
 
 
440
static inline int ha_delete_table(Session *session, const char *path,
 
441
                    const char *db, const char *alias, bool generate_warning)
 
442
{
 
443
  return drizzled::plugin::StorageEngine::deleteTable(session, path, db,
 
444
                                            alias, generate_warning);
 
445
}
 
446
 
 
447
 
 
448
#endif /* DRIZZLED_PLUGIN_STORAGE_ENGINE_H */