~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/blackhole/ha_blackhole.cc

  • Committer: Monty Taylor
  • Date: 2010-03-02 19:10:25 UTC
  • mto: (1317.1.8)
  • mto: This revision was merged to the branch mainline in revision 1322.
  • Revision ID: mordred@inaugust.com-20100302191025-zoxjz4xwkoa6160h
Prevent unauthorized users from changing schema.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
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 */
 
14
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
#include "config.h"
17
 
 
 
17
#include <drizzled/table.h>
18
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>
24
 
#include <drizzled/table.h>
25
 
 
 
19
#include "drizzled/internal/my_pthread.h"
26
20
 
27
21
#include "ha_blackhole.h"
28
22
 
29
23
#include <fcntl.h>
30
24
 
 
25
#include <string>
 
26
#include <map>
31
27
#include <fstream>
32
 
#include <map>
33
 
#include <string>
34
 
 
 
28
#include <drizzled/message/table.pb.h>
 
29
#include "drizzled/internal/m_string.h"
35
30
#include <google/protobuf/io/zero_copy_stream.h>
36
31
#include <google/protobuf/io/zero_copy_stream_impl.h>
 
32
#include "drizzled/global_charset_info.h"
37
33
 
38
34
 
39
35
using namespace std;
42
38
 
43
39
#define BLACKHOLE_EXT ".blk"
44
40
 
45
 
static pthread_mutex_t blackhole_mutex;
46
 
 
47
 
 
48
41
static const char *ha_blackhole_exts[] = {
49
 
  BLACKHOLE_EXT,
50
42
  NULL
51
43
};
52
44
 
53
45
class BlackholeEngine : public drizzled::plugin::StorageEngine
54
46
{
55
 
  typedef std::map<std::string, BlackholeShare*> BlackholeMap;
 
47
  typedef map<string, BlackholeShare*> BlackholeMap;
56
48
  BlackholeMap blackhole_open_tables;
57
49
 
58
50
public:
59
51
  BlackholeEngine(const string &name_arg)
60
 
   : drizzled::plugin::StorageEngine(name_arg,
 
52
   : drizzled::plugin::StorageEngine(name_arg, HTON_FILE_BASED |
61
53
                                     HTON_NULL_IN_KEY |
62
54
                                     HTON_CAN_INDEX_BLOBS |
63
55
                                     HTON_SKIP_STORE_LOCK |
64
 
                                     HTON_AUTO_PART_KEY),
 
56
                                     HTON_AUTO_PART_KEY |
 
57
                                     HTON_HAS_DATA_DICTIONARY),
65
58
    blackhole_open_tables()
66
59
  {
67
60
    table_definition_ext= BLACKHOLE_EXT;
68
61
  }
69
62
 
70
 
  virtual ~BlackholeEngine()
71
 
  {
72
 
    pthread_mutex_destroy(&blackhole_mutex);
73
 
  }
74
 
 
75
 
  virtual Cursor *create(Table &table)
76
 
  {
77
 
    return new ha_blackhole(*this, table);
 
63
  virtual Cursor *create(TableShare &table,
 
64
                         drizzled::memory::Root *mem_root)
 
65
  {
 
66
    return new (mem_root) ha_blackhole(*this, table);
78
67
  }
79
68
 
80
69
  const char **bas_ext() const {
81
70
    return ha_blackhole_exts;
82
71
  }
83
72
 
84
 
  int doCreateTable(Session&,
 
73
  int doCreateTable(Session*,
 
74
                    const char *,
85
75
                    Table&,
86
 
                    const drizzled::identifier::Table &identifier,
87
76
                    drizzled::message::Table&);
88
77
 
89
 
  int doDropTable(Session&, const drizzled::identifier::Table &identifier);
 
78
  int doDropTable(Session&, const string &table_name);
90
79
 
91
80
  BlackholeShare *findOpenTable(const string table_name);
92
81
  void addOpenTable(const string &table_name, BlackholeShare *);
93
82
  void deleteOpenTable(const string &table_name);
94
83
 
95
84
  int doGetTableDefinition(Session& session,
96
 
                           const drizzled::identifier::Table &identifier,
97
 
                           drizzled::message::Table &table_message);
 
85
                           const char* path,
 
86
                           const char *db,
 
87
                           const char *table_name,
 
88
                           const bool is_tmp,
 
89
                           drizzled::message::Table *table_proto);
 
90
 
 
91
  void doGetTableNames(drizzled::CachedDirectory &directory,
 
92
                       string&, set<string>& set_of_names)
 
93
  {
 
94
    drizzled::CachedDirectory::Entries entries= directory.getEntries();
 
95
 
 
96
    for (drizzled::CachedDirectory::Entries::iterator entry_iter= entries.begin();
 
97
         entry_iter != entries.end(); ++entry_iter)
 
98
    {
 
99
      drizzled::CachedDirectory::Entry *entry= *entry_iter;
 
100
      const string *filename= &entry->filename;
 
101
 
 
102
      assert(filename->size());
 
103
 
 
104
      const char *ext= strchr(filename->c_str(), '.');
 
105
 
 
106
      if (ext == NULL || my_strcasecmp(system_charset_info, ext, BLACKHOLE_EXT) ||
 
107
         (filename->compare(0, strlen(TMP_FILE_PREFIX), TMP_FILE_PREFIX) == 0))
 
108
      {  }
 
109
      else
 
110
      {
 
111
        char uname[NAME_LEN + 1];
 
112
        uint32_t file_name_len;
 
113
 
 
114
        file_name_len= filename_to_tablename(filename->c_str(), uname, sizeof(uname));
 
115
        // TODO: Remove need for memory copy here
 
116
        uname[file_name_len - sizeof(BLACKHOLE_EXT) + 1]= '\0'; // Subtract ending, place NULL
 
117
        set_of_names.insert(uname);
 
118
      }
 
119
    }
 
120
  }
98
121
 
99
122
  /* The following defines can be increased if necessary */
100
123
  uint32_t max_supported_keys()          const { return BLACKHOLE_MAX_KEY; }
110
133
            HA_KEYREAD_ONLY);
111
134
  }
112
135
 
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);
118
136
};
119
137
 
120
138
 
121
 
void BlackholeEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
122
 
                                            const drizzled::identifier::Schema &schema_identifier,
123
 
                                            drizzled::identifier::Table::vector &set_of_identifiers)
124
 
{
125
 
  drizzled::CachedDirectory::Entries entries= directory.getEntries();
126
 
 
127
 
  for (drizzled::CachedDirectory::Entries::iterator entry_iter= entries.begin();
128
 
       entry_iter != entries.end(); ++entry_iter)
129
 
  {
130
 
    drizzled::CachedDirectory::Entry *entry= *entry_iter;
131
 
    const string *filename= &entry->filename;
132
 
 
133
 
    assert(filename->size());
134
 
 
135
 
    const char *ext= strchr(filename->c_str(), '.');
136
 
 
137
 
    if (ext == NULL || my_strcasecmp(system_charset_info, ext, BLACKHOLE_EXT) ||
138
 
        (filename->compare(0, strlen(TMP_FILE_PREFIX), TMP_FILE_PREFIX) == 0))
139
 
    {  }
140
 
    else
141
 
    {
142
 
      char uname[NAME_LEN + 1];
143
 
      uint32_t file_name_len;
144
 
 
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
148
 
 
149
 
      set_of_identifiers.push_back(identifier::Table(schema_identifier, uname));
150
 
    }
151
 
  }
152
 
}
153
 
 
154
 
int BlackholeEngine::doRenameTable(Session&, const drizzled::identifier::Table &from, const drizzled::identifier::Table &to)
155
 
{
156
 
  int error= 0;
157
 
 
158
 
  for (const char **ext= bas_ext(); *ext ; ext++)
159
 
  {
160
 
    if (rename_file_ext(from.getPath().c_str(), to.getPath().c_str(), *ext))
161
 
    {
162
 
      if ((error=errno) != ENOENT)
163
 
        break;
164
 
      error= 0;
165
 
    }
166
 
  }
167
 
  return error;
168
 
}
169
 
 
170
139
BlackholeShare *BlackholeEngine::findOpenTable(const string table_name)
171
140
{
172
141
  BlackholeMap::iterator find_iter=
189
158
}
190
159
 
191
160
 
 
161
/* Static declarations for shared structures */
 
162
 
 
163
static pthread_mutex_t blackhole_mutex;
 
164
 
192
165
 
193
166
/*****************************************************************************
194
167
** BLACKHOLE tables
195
168
*****************************************************************************/
196
169
 
197
170
ha_blackhole::ha_blackhole(drizzled::plugin::StorageEngine &engine_arg,
198
 
                           Table &table_arg)
 
171
                           TableShare &table_arg)
199
172
  :Cursor(engine_arg, table_arg), share(NULL)
200
173
{ }
201
174
 
204
177
  if (!(share= get_share(name)))
205
178
    return(HA_ERR_OUT_OF_MEM);
206
179
 
207
 
  lock.init(&share->lock);
208
 
  return 0;
 
180
  thr_lock_data_init(&share->lock, &lock, NULL);
 
181
  return(0);
209
182
}
210
183
 
211
184
int ha_blackhole::close(void)
214
187
  return 0;
215
188
}
216
189
 
217
 
int BlackholeEngine::doCreateTable(Session&,
 
190
int BlackholeEngine::doCreateTable(Session*, const char *path,
218
191
                                   Table&,
219
 
                                   const drizzled::identifier::Table &identifier,
220
192
                                   drizzled::message::Table& proto)
221
193
{
222
194
  string serialized_proto;
223
195
  string new_path;
224
196
 
225
 
  new_path= identifier.getPath();
 
197
  new_path= path;
226
198
  new_path+= BLACKHOLE_EXT;
227
199
  fstream output(new_path.c_str(), ios::out | ios::binary);
228
200
 
241
213
}
242
214
 
243
215
 
244
 
int BlackholeEngine::doDropTable(Session&,
245
 
                                 const drizzled::identifier::Table &identifier)
 
216
int BlackholeEngine::doDropTable(Session&, const string &path)
246
217
{
247
 
  string new_path(identifier.getPath());
 
218
  string new_path(path);
248
219
 
249
220
  new_path+= BLACKHOLE_EXT;
250
221
 
259
230
}
260
231
 
261
232
 
262
 
bool BlackholeEngine::doDoesTableExist(Session&,
263
 
                                       const drizzled::identifier::Table &identifier)
264
 
{
265
 
  string proto_path(identifier.getPath());
266
 
  proto_path.append(BLACKHOLE_EXT);
267
 
 
268
 
  if (access(proto_path.c_str(), F_OK))
269
 
  {
270
 
    return false;
271
 
  }
272
 
 
273
 
  return true;
274
 
}
275
 
 
276
 
 
277
233
int BlackholeEngine::doGetTableDefinition(Session&,
278
 
                                          const drizzled::identifier::Table &identifier,
279
 
                                          drizzled::message::Table &table_proto)
 
234
                                          const char* path,
 
235
                                          const char *,
 
236
                                          const char *,
 
237
                                          const bool,
 
238
                                          drizzled::message::Table *table_proto)
280
239
{
281
240
  string new_path;
282
241
 
283
 
  new_path= identifier.getPath();
 
242
  new_path= path;
284
243
  new_path+= BLACKHOLE_EXT;
285
244
 
286
245
  int fd= open(new_path.c_str(), O_RDONLY);
293
252
  google::protobuf::io::ZeroCopyInputStream* input=
294
253
    new google::protobuf::io::FileInputStream(fd);
295
254
 
296
 
  if (not input)
 
255
  if (! input)
297
256
    return HA_ERR_CRASHED_ON_USAGE;
298
257
 
299
 
  if (not table_proto.ParseFromZeroCopyStream(input))
 
258
  if (table_proto && ! table_proto->ParseFromZeroCopyStream(input))
300
259
  {
301
260
    close(fd);
302
261
    delete input;
303
 
    if (not table_proto.IsInitialized())
 
262
    if (! table_proto->IsInitialized())
304
263
    {
305
264
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
306
 
               table_proto.name().empty() ? " " : table_proto.name().c_str(),
307
 
               table_proto.InitializationErrorString().c_str());
308
 
 
 
265
               table_proto->InitializationErrorString().c_str());
309
266
      return ER_CORRUPT_TABLE_DEFINITION;
310
267
    }
311
268
 
313
270
  }
314
271
 
315
272
  delete input;
316
 
 
317
273
  return EEXIST;
318
274
}
319
275
 
322
278
  return("BTREE");
323
279
}
324
280
 
325
 
int ha_blackhole::doInsertRecord(unsigned char *)
 
281
int ha_blackhole::write_row(unsigned char *)
326
282
{
327
 
  return(getTable()->next_number_field ? update_auto_increment() : 0);
 
283
  return(table->next_number_field ? update_auto_increment() : 0);
328
284
}
329
285
 
330
 
int ha_blackhole::doStartTableScan(bool)
 
286
int ha_blackhole::rnd_init(bool)
331
287
{
332
288
  return(0);
333
289
}
410
366
{
411
367
  pthread_mutex_lock(&blackhole_mutex);
412
368
 
413
 
  BlackholeEngine *a_engine= static_cast<BlackholeEngine *>(getEngine());
 
369
  BlackholeEngine *a_engine= static_cast<BlackholeEngine *>(engine);
414
370
  share= a_engine->findOpenTable(table_name);
415
371
 
416
372
  if (share == NULL)
435
391
  pthread_mutex_lock(&blackhole_mutex);
436
392
  if (!--share->use_count)
437
393
  {
438
 
    BlackholeEngine *a_engine= static_cast<BlackholeEngine *>(getEngine());
 
394
    BlackholeEngine *a_engine= static_cast<BlackholeEngine *>(engine);
439
395
    a_engine->deleteOpenTable(share->table_name);
440
396
    delete share;
441
397
  }
450
406
 
451
407
BlackholeShare::~BlackholeShare()
452
408
{
453
 
  lock.deinit();
 
409
  thr_lock_delete(&lock);
454
410
}
455
411
 
456
412
 
457
413
static drizzled::plugin::StorageEngine *blackhole_engine= NULL;
458
414
 
459
 
static int blackhole_init(drizzled::module::Context &context)
 
415
static int blackhole_init(drizzled::plugin::Registry &registry)
460
416
{
461
417
 
462
418
  blackhole_engine= new BlackholeEngine("BLACKHOLE");
463
 
  context.add(blackhole_engine);
 
419
  registry.add(blackhole_engine);
464
420
  
465
421
  pthread_mutex_init(&blackhole_mutex, MY_MUTEX_INIT_FAST);
466
422
 
467
423
  return 0;
468
424
}
469
425
 
 
426
static int blackhole_fini(drizzled::plugin::Registry &registry)
 
427
{
 
428
  registry.remove(blackhole_engine);
 
429
  delete blackhole_engine;
 
430
 
 
431
  pthread_mutex_destroy(&blackhole_mutex);
 
432
 
 
433
  return 0;
 
434
}
470
435
 
471
436
DRIZZLE_DECLARE_PLUGIN
472
437
{
477
442
  "/dev/null storage engine (anything you write to it disappears)",
478
443
  PLUGIN_LICENSE_GPL,
479
444
  blackhole_init,     /* Plugin Init */
480
 
  NULL,               /* depends */
 
445
  blackhole_fini,     /* Plugin Deinit */
 
446
  NULL,               /* system variables */
481
447
  NULL                /* config options   */
482
448
}
483
449
DRIZZLE_DECLARE_PLUGIN_END;