~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/storage_engine.cc

  • Committer: Brian Aker
  • Date: 2010-06-28 16:17:36 UTC
  • mfrom: (1637.4.1 drizzle)
  • Revision ID: brian@gaz-20100628161736-eormhb2mnd551i2h
MergeĀ unused

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
32
32
#include <google/protobuf/io/zero_copy_stream.h>
33
33
#include <google/protobuf/io/zero_copy_stream_impl.h>
34
34
 
 
35
#include "drizzled/my_hash.h"
35
36
#include "drizzled/cached_directory.h"
36
37
 
37
38
#include <drizzled/definitions.h>
54
55
#include <drizzled/table_proto.h>
55
56
#include <drizzled/plugin/event_observer.h>
56
57
 
57
 
#include <drizzled/table/shell.h>
58
 
 
59
 
#include "drizzled/message/cache.h"
60
 
 
61
 
#include <boost/algorithm/string/compare.hpp>
62
 
 
63
58
static bool shutdown_has_begun= false; // Once we put in the container for the vector/etc for engines this will go away.
64
59
 
 
60
using namespace std;
 
61
 
65
62
namespace drizzled
66
63
{
67
64
 
71
68
static EngineVector vector_of_engines;
72
69
static EngineVector vector_of_schema_engines;
73
70
 
74
 
const std::string DEFAULT_STRING("default");
75
71
const std::string UNKNOWN_STRING("UNKNOWN");
76
72
const std::string DEFAULT_DEFINITION_FILE_EXT(".dfe");
77
73
 
82
78
  return vector_of_schema_engines;
83
79
}
84
80
 
85
 
StorageEngine::StorageEngine(const std::string name_arg,
86
 
                             const std::bitset<HTON_BIT_SIZE> &flags_arg) :
 
81
StorageEngine::StorageEngine(const string name_arg,
 
82
                             const bitset<HTON_BIT_SIZE> &flags_arg) :
87
83
  Plugin(name_arg, "StorageEngine"),
88
84
  MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
89
85
  flags(flags_arg)
101
97
}
102
98
 
103
99
 
104
 
int StorageEngine::renameTable(Session &session, const identifier::Table &from, const identifier::Table &to)
 
100
int StorageEngine::renameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
105
101
{
106
102
  int error;
107
103
  setTransactionReadWrite(session);
137
133
  @retval
138
134
    !0  Error
139
135
*/
140
 
int StorageEngine::doDropTable(Session&, const identifier::Table &identifier)
 
136
int StorageEngine::doDropTable(Session&, const TableIdentifier &identifier)
141
137
                               
142
138
{
143
139
  int error= 0;
192
188
}
193
189
 
194
190
class FindEngineByName
195
 
  : public std::unary_function<StorageEngine *, bool>
 
191
  : public unary_function<StorageEngine *, bool>
196
192
{
197
 
  const std::string &predicate;
 
193
  const string &target;
198
194
 
199
195
public:
200
 
  explicit FindEngineByName(const std::string &target_arg) :
201
 
    predicate(target_arg)
 
196
  explicit FindEngineByName(const string &target_arg) :
 
197
    target(target_arg)
202
198
  {
203
199
  }
204
 
 
205
200
  result_type operator() (argument_type engine)
206
201
  {
207
 
    return boost::iequals(engine->getName(), predicate);
 
202
    string engine_name(engine->getName());
 
203
 
 
204
    transform(engine_name.begin(), engine_name.end(),
 
205
              engine_name.begin(), ::tolower);
 
206
    return engine_name == target;
208
207
  }
209
208
};
210
209
 
211
 
StorageEngine *StorageEngine::findByName(const std::string &predicate)
 
210
StorageEngine *StorageEngine::findByName(const string &find_str)
212
211
{
213
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
214
 
                                            vector_of_engines.end(),
215
 
                                            FindEngineByName(predicate));
 
212
  string search_string(find_str);
 
213
  transform(search_string.begin(), search_string.end(),
 
214
            search_string.begin(), ::tolower);
 
215
 
 
216
  
 
217
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
 
218
                                       vector_of_engines.end(),
 
219
                                       FindEngineByName(search_string));
216
220
  if (iter != vector_of_engines.end())
217
221
  {
218
222
    StorageEngine *engine= *iter;
223
227
  return NULL;
224
228
}
225
229
 
226
 
StorageEngine *StorageEngine::findByName(Session& session, const std::string &predicate)
 
230
StorageEngine *StorageEngine::findByName(Session& session, const string &find_str)
227
231
{
228
 
  if (boost::iequals(predicate, DEFAULT_STRING))
 
232
  string search_string(find_str);
 
233
  transform(search_string.begin(), search_string.end(),
 
234
            search_string.begin(), ::tolower);
 
235
 
 
236
  if (search_string.compare("default") == 0)
229
237
    return session.getDefaultStorageEngine();
230
238
 
231
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
232
 
                                            vector_of_engines.end(),
233
 
                                            FindEngineByName(predicate));
 
239
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
 
240
                                       vector_of_engines.end(),
 
241
                                       FindEngineByName(search_string));
234
242
  if (iter != vector_of_engines.end())
235
243
  {
236
244
    StorageEngine *engine= *iter;
241
249
  return NULL;
242
250
}
243
251
 
244
 
class StorageEngineCloseConnection : public std::unary_function<StorageEngine *, void>
 
252
class StorageEngineCloseConnection : public unary_function<StorageEngine *, void>
245
253
{
246
254
  Session *session;
247
255
public:
263
271
*/
264
272
void StorageEngine::closeConnection(Session* session)
265
273
{
266
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
267
 
                StorageEngineCloseConnection(session));
 
274
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
275
           StorageEngineCloseConnection(session));
268
276
}
269
277
 
270
278
bool StorageEngine::flushLogs(StorageEngine *engine)
271
279
{
272
280
  if (engine == NULL)
273
281
  {
274
 
    if (std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
 
                     std::mem_fun(&StorageEngine::flush_logs))
 
282
    if (find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
283
                mem_fun(&StorageEngine::flush_logs))
276
284
        != vector_of_engines.begin())
277
285
      return true;
278
286
  }
284
292
  return false;
285
293
}
286
294
 
287
 
class StorageEngineGetTableDefinition: public std::unary_function<StorageEngine *,bool>
 
295
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
288
296
{
289
297
  Session& session;
290
 
  const identifier::Table &identifier;
 
298
  const TableIdentifier &identifier;
291
299
  message::Table &table_message;
292
 
  drizzled::error_t &err;
 
300
  int &err;
293
301
 
294
302
public:
295
303
  StorageEngineGetTableDefinition(Session& session_arg,
296
 
                                  const identifier::Table &identifier_arg,
 
304
                                  const TableIdentifier &identifier_arg,
297
305
                                  message::Table &table_message_arg,
298
 
                                  drizzled::error_t &err_arg) :
 
306
                                  int &err_arg) :
299
307
    session(session_arg), 
300
308
    identifier(identifier_arg),
301
309
    table_message(table_message_arg), 
306
314
    int ret= engine->doGetTableDefinition(session, identifier, table_message);
307
315
 
308
316
    if (ret != ENOENT)
309
 
      err= static_cast<drizzled::error_t>(ret);
 
317
      err= ret;
310
318
 
311
 
    return err == static_cast<drizzled::error_t>(EEXIST) or err != static_cast<drizzled::error_t>(ENOENT);
 
319
    return err == EEXIST || err != ENOENT;
312
320
  }
313
321
};
314
322
 
315
 
class StorageEngineDoesTableExist: public std::unary_function<StorageEngine *, bool>
 
323
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
316
324
{
317
325
  Session& session;
318
 
  const identifier::Table &identifier;
 
326
  const TableIdentifier &identifier;
319
327
 
320
328
public:
321
 
  StorageEngineDoesTableExist(Session& session_arg, const identifier::Table &identifier_arg) :
 
329
  StorageEngineDoesTableExist(Session& session_arg, const TableIdentifier &identifier_arg) :
322
330
    session(session_arg), 
323
331
    identifier(identifier_arg) 
324
332
  { }
333
341
  Utility method which hides some of the details of getTableDefinition()
334
342
*/
335
343
bool plugin::StorageEngine::doesTableExist(Session &session,
336
 
                                           const identifier::Table &identifier,
 
344
                                           const TableIdentifier &identifier,
337
345
                                           bool include_temporary_tables)
338
346
{
339
347
  if (include_temporary_tables)
343
351
  }
344
352
 
345
353
  EngineVector::iterator iter=
346
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
347
 
                 StorageEngineDoesTableExist(session, identifier));
 
354
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
355
            StorageEngineDoesTableExist(session, identifier));
348
356
 
349
357
  if (iter == vector_of_engines.end())
350
358
  {
354
362
  return true;
355
363
}
356
364
 
357
 
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::identifier::Table&)
 
365
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::TableIdentifier&)
358
366
{
359
 
  std::cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
 
367
  cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
360
368
  assert(0);
361
369
  return false;
362
370
}
367
375
  or any dropped tables that need to be removed from disk
368
376
*/
369
377
int StorageEngine::getTableDefinition(Session& session,
370
 
                                      const identifier::Table &identifier,
371
 
                                      message::table::shared_ptr &table_message,
 
378
                                      const TableIdentifier &identifier,
 
379
                                      message::Table &table_message,
372
380
                                      bool include_temporary_tables)
373
381
{
374
 
  drizzled::error_t err= static_cast<drizzled::error_t>(ENOENT);
 
382
  int err= ENOENT;
375
383
 
376
384
  if (include_temporary_tables)
377
385
  {
378
 
    Table *table= session.find_temporary_table(identifier);
379
 
    if (table)
380
 
    {
381
 
      table_message.reset(new message::Table(*table->getShare()->getTableMessage()));
 
386
    if (session.doGetTableDefinition(identifier, table_message) == EEXIST)
382
387
      return EEXIST;
383
 
    }
384
 
  }
385
 
 
386
 
  drizzled::message::table::shared_ptr table_ptr;
387
 
  if ((table_ptr= drizzled::message::Cache::singleton().find(identifier)))
388
 
  {
389
 
    table_message= table_ptr;
390
 
  }
391
 
 
392
 
  message::Table message;
 
388
  }
 
389
 
393
390
  EngineVector::iterator iter=
394
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
395
 
                 StorageEngineGetTableDefinition(session, identifier, message, err));
 
391
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
392
            StorageEngineGetTableDefinition(session, identifier, table_message, err));
396
393
 
397
394
  if (iter == vector_of_engines.end())
398
395
  {
399
396
    return ENOENT;
400
397
  }
401
 
  table_message.reset(new message::Table(message));
402
 
 
403
 
 drizzled::message::Cache::singleton().insert(identifier, table_message);
404
398
 
405
399
  return err;
406
400
}
407
401
 
408
 
message::table::shared_ptr StorageEngine::getTableMessage(Session& session,
409
 
                                                          identifier::Table::const_reference identifier,
410
 
                                                          drizzled::error_t &error,
411
 
                                                          bool include_temporary_tables)
412
 
{
413
 
  error= static_cast<drizzled::error_t>(ENOENT);
414
 
 
415
 
  if (include_temporary_tables)
416
 
  {
417
 
    Table *table= session.find_temporary_table(identifier);
418
 
    if (table)
419
 
    {
420
 
      error= EE_OK;
421
 
      return message::table::shared_ptr(new message::Table(*table->getShare()->getTableMessage()));
422
 
    }
423
 
  }
424
 
 
425
 
  drizzled::message::table::shared_ptr table_ptr;
426
 
  if ((table_ptr= drizzled::message::Cache::singleton().find(identifier)))
427
 
  {
428
 
    (void)table_ptr;
429
 
  }
430
 
 
431
 
  message::Table message;
432
 
  EngineVector::iterator iter=
433
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
434
 
                 StorageEngineGetTableDefinition(session, identifier, message, error));
435
 
 
436
 
  if (iter == vector_of_engines.end())
437
 
  {
438
 
    error= static_cast<drizzled::error_t>(ENOENT);
439
 
    return message::table::shared_ptr();
440
 
  }
441
 
  message::table::shared_ptr table_message(new message::Table(message));
442
 
 
443
 
  drizzled::message::Cache::singleton().insert(identifier, table_message);
444
 
 
445
 
  return table_message;
446
 
}
447
 
 
448
402
/**
449
403
  An interceptor to hijack the text of the error message without
450
404
  setting an error in the thread. We need the text to present it
455
409
{
456
410
public:
457
411
  Ha_delete_table_error_handler() : Internal_error_handler() {}
458
 
  virtual bool handle_error(drizzled::error_t sql_errno,
 
412
  virtual bool handle_error(uint32_t sql_errno,
459
413
                            const char *message,
460
414
                            DRIZZLE_ERROR::enum_warning_level level,
461
415
                            Session *session);
465
419
 
466
420
bool
467
421
Ha_delete_table_error_handler::
468
 
handle_error(drizzled::error_t ,
 
422
handle_error(uint32_t ,
469
423
             const char *message,
470
424
             DRIZZLE_ERROR::enum_warning_level ,
471
425
             Session *)
475
429
  return true;
476
430
}
477
431
 
478
 
class DropTableByIdentifier: public std::unary_function<EngineVector::value_type, bool>
479
 
{
480
 
  Session::reference session;
481
 
  identifier::Table::const_reference identifier;
482
 
  drizzled::error_t &error;
483
 
 
484
 
public:
485
 
 
486
 
  DropTableByIdentifier(Session::reference session_arg,
487
 
                        identifier::Table::const_reference identifier_arg,
488
 
                        drizzled::error_t &error_arg) :
489
 
    session(session_arg),
490
 
    identifier(identifier_arg),
491
 
    error(error_arg)
492
 
  { }
493
 
 
494
 
  result_type operator() (argument_type engine)
495
 
  {
496
 
    if (not engine->doDoesTableExist(session, identifier))
497
 
      return false;
498
 
 
499
 
    int local_error= engine->doDropTable(session, identifier);
500
 
 
501
 
 
502
 
    if (not local_error)
503
 
      return true;
504
 
 
505
 
    switch (local_error)
506
 
    {
507
 
    case HA_ERR_NO_SUCH_TABLE:
508
 
    case ENOENT:
509
 
      error= static_cast<drizzled::error_t>(HA_ERR_NO_SUCH_TABLE);
510
 
      return false;
511
 
 
512
 
    default:
513
 
      error= static_cast<drizzled::error_t>(local_error);
514
 
      return true;
515
 
    }
516
 
  } 
517
 
};
518
 
 
519
 
 
520
 
bool StorageEngine::dropTable(Session::reference session,
521
 
                              identifier::Table::const_reference identifier,
522
 
                              drizzled::error_t &error)
523
 
{
524
 
  error= EE_OK;
525
 
 
526
 
  EngineVector::const_iterator iter= std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
527
 
                                                  DropTableByIdentifier(session, identifier, error));
528
 
 
529
 
  if (error)
530
 
  {
531
 
    return false;
532
 
  }
533
 
  else if (iter == vector_of_engines.end())
534
 
  {
535
 
    error= ER_BAD_TABLE_ERROR;
536
 
    return false;
537
 
  }
538
 
 
539
 
  drizzled::message::Cache::singleton().erase(identifier);
540
 
 
541
 
  return true;
542
 
}
543
 
 
544
 
bool StorageEngine::dropTable(Session& session,
545
 
                              const identifier::Table &identifier)
546
 
{
547
 
  drizzled::error_t error;
548
 
 
549
 
  if (not dropTable(session, identifier, error))
550
 
  {
551
 
    return false;
552
 
  }
553
 
 
554
 
  return true;
555
 
}
556
 
 
557
 
bool StorageEngine::dropTable(Session::reference session,
558
 
                              StorageEngine &engine,
559
 
                              identifier::Table::const_reference identifier,
560
 
                              drizzled::error_t &error)
561
 
{
562
 
  error= EE_OK;
 
432
/**
 
433
   returns ENOENT if the file doesn't exists.
 
434
*/
 
435
int StorageEngine::dropTable(Session& session,
 
436
                             const TableIdentifier &identifier)
 
437
{
 
438
  int error= 0;
 
439
  int error_proto;
 
440
  message::Table src_proto;
 
441
  StorageEngine *engine;
 
442
 
 
443
  error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
 
444
 
 
445
  if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
 
446
  {
 
447
    string error_message;
 
448
 
 
449
    error_message.append(const_cast<TableIdentifier &>(identifier).getSQLPath());
 
450
    error_message.append(" : ");
 
451
    error_message.append(src_proto.InitializationErrorString());
 
452
 
 
453
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
 
454
 
 
455
    return ER_CORRUPT_TABLE_DEFINITION;
 
456
  }
 
457
 
 
458
  engine= StorageEngine::findByName(session, src_proto.engine().name());
 
459
 
 
460
  if (not engine)
 
461
  {
 
462
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str());
 
463
 
 
464
    return ER_CORRUPT_TABLE_DEFINITION;
 
465
  }
 
466
 
 
467
  error= StorageEngine::dropTable(session, *engine, identifier);
 
468
 
 
469
  if (error_proto && error == 0)
 
470
    return 0;
 
471
 
 
472
  return error;
 
473
}
 
474
 
 
475
int StorageEngine::dropTable(Session& session,
 
476
                             StorageEngine &engine,
 
477
                             const TableIdentifier &identifier)
 
478
{
 
479
  int error;
 
480
 
563
481
  engine.setTransactionReadWrite(session);
564
 
 
565
 
  assert(identifier.isTmp());
566
482
  
567
483
  if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
568
484
  {
570
486
  }
571
487
  else
572
488
  {
573
 
    error= static_cast<drizzled::error_t>(engine.doDropTable(session, identifier));
574
 
 
 
489
    error= engine.doDropTable(session, identifier);
575
490
    if (unlikely(plugin::EventObserver::afterDropTable(session, identifier, error)))
576
491
    {
577
492
      error= ER_EVENT_OBSERVER_PLUGIN;
578
493
    }
579
494
  }
580
495
 
581
 
  drizzled::message::Cache::singleton().erase(identifier);
582
 
 
583
 
  if (error)
584
 
  {
585
 
    return false;
586
 
  }
587
 
 
588
 
  return true;
 
496
 
 
497
  return error;
589
498
}
590
499
 
591
500
 
597
506
  @retval
598
507
   1  error
599
508
*/
600
 
bool StorageEngine::createTable(Session &session,
601
 
                                const identifier::Table &identifier,
602
 
                                message::Table& table_message)
 
509
int StorageEngine::createTable(Session &session,
 
510
                               const TableIdentifier &identifier,
 
511
                               message::Table& table_message)
603
512
{
604
 
  drizzled::error_t error= EE_OK;
605
 
 
 
513
  int error= 1;
 
514
  Table table;
606
515
  TableShare share(identifier);
607
 
  table::Shell table(share);
608
516
  message::Table tmp_proto;
609
517
 
610
518
  if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
611
519
  { 
612
520
    // @note Error occured, we should probably do a little more here.
613
 
    // ER_CORRUPT_TABLE_DEFINITION,ER_CORRUPT_TABLE_DEFINITION_ENUM 
614
 
    
615
 
    my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN, identifier);
616
 
 
617
 
    return false;
618
521
  }
619
522
  else
620
523
  {
633
536
    {
634
537
      share.storage_engine->setTransactionReadWrite(session);
635
538
 
636
 
      error= static_cast<drizzled::error_t>(share.storage_engine->doCreateTable(session,
637
 
                                                                                table,
638
 
                                                                                identifier,
639
 
                                                                                table_message));
640
 
    }
641
 
 
642
 
    if (error == ER_TABLE_PERMISSION_DENIED)
643
 
    {
644
 
      my_error(ER_TABLE_PERMISSION_DENIED, identifier);
645
 
    }
646
 
    else if (error)
647
 
    {
648
 
      std::string path;
649
 
      identifier.getSQLPath(path);
650
 
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), path.c_str(), error);
651
 
    }
652
 
 
653
 
    table.delete_table();
654
 
  }
655
 
 
656
 
  return(error == EE_OK);
657
 
}
658
 
 
659
 
Cursor *StorageEngine::getCursor(Table &arg)
660
 
{
661
 
  return create(arg);
662
 
}
 
539
      error= share.storage_engine->doCreateTable(session,
 
540
                                                 table,
 
541
                                                 identifier,
 
542
                                                 table_message);
 
543
    }
 
544
 
 
545
    if (error)
 
546
    {
 
547
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
 
548
    }
 
549
 
 
550
    table.delete_table(false);
 
551
  }
 
552
 
 
553
  return(error != 0);
 
554
}
 
555
 
 
556
Cursor *StorageEngine::getCursor(TableShare &share, memory::Root *alloc)
 
557
{
 
558
  return create(share, alloc);
 
559
}
 
560
 
 
561
class AddTableName : 
 
562
  public unary_function<StorageEngine *, void>
 
563
{
 
564
  CachedDirectory &directory;
 
565
  SchemaIdentifier &identifier;
 
566
  TableNameList &set_of_names;
 
567
 
 
568
public:
 
569
 
 
570
  AddTableName(CachedDirectory &directory_arg, SchemaIdentifier &identifier_arg, set<string>& of_names) :
 
571
    directory(directory_arg),
 
572
    identifier(identifier_arg),
 
573
    set_of_names(of_names)
 
574
  {
 
575
  }
 
576
 
 
577
  result_type operator() (argument_type engine)
 
578
  {
 
579
    engine->doGetTableNames(directory, identifier, set_of_names);
 
580
  }
 
581
};
663
582
 
664
583
class AddTableIdentifier : 
665
 
  public std::unary_function<StorageEngine *, void>
 
584
  public unary_function<StorageEngine *, void>
666
585
{
667
586
  CachedDirectory &directory;
668
 
  const identifier::Schema &identifier;
669
 
  identifier::Table::vector &set_of_identifiers;
 
587
  SchemaIdentifier &identifier;
 
588
  TableIdentifiers &set_of_identifiers;
670
589
 
671
590
public:
672
591
 
673
 
  AddTableIdentifier(CachedDirectory &directory_arg, const identifier::Schema &identifier_arg, identifier::Table::vector &of_names) :
 
592
  AddTableIdentifier(CachedDirectory &directory_arg, SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
674
593
    directory(directory_arg),
675
594
    identifier(identifier_arg),
676
595
    set_of_identifiers(of_names)
684
603
};
685
604
 
686
605
 
687
 
void StorageEngine::getIdentifiers(Session &session, const identifier::Schema &schema_identifier, identifier::Table::vector &set_of_identifiers)
688
 
{
689
 
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
690
 
 
691
 
  if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
692
 
  { }
693
 
  else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
694
 
  { }
695
 
  else
696
 
  {
697
 
    if (directory.fail())
698
 
    {
699
 
      errno= directory.getError();
700
 
      if (errno == ENOENT)
701
 
      {
702
 
        std::string path;
703
 
        schema_identifier.getSQLPath(path);
704
 
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), path.c_str());
705
 
      }
706
 
      else
707
 
      {
708
 
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
709
 
      }
710
 
 
711
 
      return;
712
 
    }
713
 
  }
714
 
 
715
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
716
 
                AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
 
606
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
 
607
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
 
608
 
 
609
void StorageEngine::getTableNames(Session &session, SchemaIdentifier &schema_identifier, TableNameList &set_of_names)
 
610
{
 
611
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
 
612
 
 
613
  if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
 
614
  { }
 
615
  else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
 
616
  { }
 
617
  else
 
618
  {
 
619
    if (directory.fail())
 
620
    {
 
621
      errno= directory.getError();
 
622
      if (errno == ENOENT)
 
623
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
 
624
      else
 
625
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
 
626
      return;
 
627
    }
 
628
  }
 
629
 
 
630
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
631
           AddTableName(directory, schema_identifier, set_of_names));
 
632
 
 
633
  session.doGetTableNames(directory, schema_identifier, set_of_names);
 
634
}
 
635
 
 
636
void StorageEngine::getTableIdentifiers(Session &session, SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
 
637
{
 
638
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
 
639
 
 
640
  if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
 
641
  { }
 
642
  else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
 
643
  { }
 
644
  else
 
645
  {
 
646
    if (directory.fail())
 
647
    {
 
648
      errno= directory.getError();
 
649
      if (errno == ENOENT)
 
650
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
 
651
      else
 
652
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
 
653
      return;
 
654
    }
 
655
  }
 
656
 
 
657
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
658
           AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
717
659
 
718
660
  session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
719
661
}
720
662
 
721
 
class DropTable: public std::unary_function<identifier::Table&, bool>
 
663
class DropTable: public unary_function<TableIdentifier&, bool>
722
664
{
723
665
  Session &session;
724
666
  StorageEngine *engine;
736
678
  } 
737
679
};
738
680
 
739
 
/* This will later be converted to identifier::Tables */
740
 
class DropTables: public std::unary_function<StorageEngine *, void>
 
681
/* This will later be converted to TableIdentifiers */
 
682
class DropTables: public unary_function<StorageEngine *, void>
741
683
{
742
684
  Session &session;
743
 
  identifier::Table::vector &table_identifiers;
 
685
  TableIdentifierList &table_identifiers;
744
686
 
745
687
public:
746
688
 
747
 
  DropTables(Session &session_arg, identifier::Table::vector &table_identifiers_arg) :
 
689
  DropTables(Session &session_arg, TableIdentifierList &table_identifiers_arg) :
748
690
    session(session_arg),
749
691
    table_identifiers(table_identifiers_arg)
750
692
  { }
753
695
  {
754
696
    // True returning from DropTable means the table has been successfully
755
697
    // deleted, so it should be removed from the list of tables to drop
756
 
    table_identifiers.erase(std::remove_if(table_identifiers.begin(),
757
 
                                           table_identifiers.end(),
758
 
                                           DropTable(session, engine)),
 
698
    table_identifiers.erase(remove_if(table_identifiers.begin(),
 
699
                                      table_identifiers.end(),
 
700
                                      DropTable(session, engine)),
759
701
                            table_identifiers.end());
760
702
  }
761
703
};
768
710
void StorageEngine::removeLostTemporaryTables(Session &session, const char *directory)
769
711
{
770
712
  CachedDirectory dir(directory, set_of_table_definition_ext);
771
 
  identifier::Table::vector table_identifiers;
 
713
  TableIdentifierList table_identifiers;
772
714
 
773
715
  if (dir.fail())
774
716
  {
784
726
       fileIter != files.end(); fileIter++)
785
727
  {
786
728
    size_t length;
787
 
    std::string path;
 
729
    string path;
788
730
    CachedDirectory::Entry *entry= *fileIter;
789
731
 
790
732
    /* We remove the file extension. */
797
739
    message::Table definition;
798
740
    if (StorageEngine::readTableFile(path, definition))
799
741
    {
800
 
      identifier::Table identifier(definition.schema(), definition.name(), path);
 
742
      TableIdentifier identifier(definition.schema(), definition.name(), path);
801
743
      table_identifiers.push_back(identifier);
802
744
    }
803
745
  }
804
746
 
805
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
806
 
                DropTables(session, table_identifiers));
807
 
 
 
747
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
748
           DropTables(session, table_identifiers));
 
749
  
808
750
  /*
809
751
    Now we just clean up anything that might left over.
810
752
 
811
753
    We rescan because some of what might have been there should
812
754
    now be all nice and cleaned up.
813
755
  */
814
 
  std::set<std::string> all_exts= set_of_table_definition_ext;
 
756
  set<string> all_exts= set_of_table_definition_ext;
815
757
 
816
758
  for (EngineVector::iterator iter= vector_of_engines.begin();
817
759
       iter != vector_of_engines.end() ; iter++)
826
768
  for (CachedDirectory::Entries::iterator fileIter= files.begin();
827
769
       fileIter != files.end(); fileIter++)
828
770
  {
829
 
    std::string path;
 
771
    string path;
830
772
    CachedDirectory::Entry *entry= *fileIter;
831
773
 
832
774
    path+= directory;
847
789
    - table->getShare()->path
848
790
    - table->alias
849
791
*/
850
 
void StorageEngine::print_error(int error, myf errflag, const Table &table) const
851
 
{
852
 
  drizzled::error_t textno= ER_GET_ERRNO;
 
792
void StorageEngine::print_error(int error, myf errflag, Table &table)
 
793
{
 
794
  print_error(error, errflag, &table);
 
795
}
 
796
 
 
797
void StorageEngine::print_error(int error, myf errflag, Table *table)
 
798
{
 
799
  int textno= ER_GET_ERRNO;
853
800
  switch (error) {
854
801
  case EACCES:
855
802
    textno=ER_OPEN_AS_READONLY;
870
817
    break;
871
818
  case HA_ERR_FOUND_DUPP_KEY:
872
819
  {
873
 
    uint32_t key_nr= table.get_dup_key(error);
 
820
    assert(table);
 
821
    uint32_t key_nr= table->get_dup_key(error);
874
822
    if ((int) key_nr >= 0)
875
823
    {
876
824
      const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
877
825
 
878
 
      print_keydup_error(key_nr, err_msg, table);
 
826
      print_keydup_error(key_nr, err_msg, *table);
879
827
 
880
828
      return;
881
829
    }
884
832
  }
885
833
  case HA_ERR_FOREIGN_DUPLICATE_KEY:
886
834
  {
887
 
    uint32_t key_nr= table.get_dup_key(error);
 
835
    assert(table);
 
836
    uint32_t key_nr= table->get_dup_key(error);
888
837
    if ((int) key_nr >= 0)
889
838
    {
890
839
      uint32_t max_length;
894
843
      String str(key,sizeof(key),system_charset_info);
895
844
 
896
845
      /* Table is opened and defined at this point */
897
 
      key_unpack(&str, &table,(uint32_t) key_nr);
 
846
      key_unpack(&str,table,(uint32_t) key_nr);
898
847
      max_length= (DRIZZLE_ERRMSG_SIZE-
899
848
                   (uint32_t) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
900
849
      if (str.length() >= max_length)
902
851
        str.length(max_length-4);
903
852
        str.append(STRING_WITH_LEN("..."));
904
853
      }
905
 
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table.getShare()->getTableName(),
 
854
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table->getShare()->getTableName(),
906
855
        str.c_ptr(), key_nr+1);
907
856
      return;
908
857
    }
925
874
    textno=ER_CRASHED_ON_USAGE;
926
875
    break;
927
876
  case HA_ERR_NOT_A_TABLE:
928
 
    textno= static_cast<drizzled::error_t>(error);
 
877
    textno= error;
929
878
    break;
930
879
  case HA_ERR_CRASHED_ON_REPAIR:
931
880
    textno=ER_CRASHED_ON_REPAIR;
979
928
    textno=ER_TABLE_DEF_CHANGED;
980
929
    break;
981
930
  case HA_ERR_NO_SUCH_TABLE:
982
 
    {
983
 
      identifier::Table identifier(table.getShare()->getSchemaName(), table.getShare()->getTableName());
984
 
      my_error(ER_TABLE_UNKNOWN, identifier);
985
 
      return;
986
 
    }
 
931
    assert(table);
 
932
    my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
 
933
             table->getShare()->getTableName());
 
934
    return;
987
935
  case HA_ERR_RBR_LOGGING_FAILED:
988
936
    textno= ER_BINLOG_ROW_LOGGING_FAILED;
989
937
    break;
990
938
  case HA_ERR_DROP_INDEX_FK:
991
939
  {
 
940
    assert(table);
992
941
    const char *ptr= "???";
993
 
    uint32_t key_nr= table.get_dup_key(error);
 
942
    uint32_t key_nr= table->get_dup_key(error);
994
943
    if ((int) key_nr >= 0)
995
 
      ptr= table.key_info[key_nr].name;
 
944
      ptr= table->key_info[key_nr].name;
996
945
    my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
997
946
    return;
998
947
  }
1037
986
      return;
1038
987
    }
1039
988
  }
1040
 
 
1041
 
  my_error(textno, errflag, table.getShare()->getTableName(), error);
 
989
  my_error(textno, errflag, table->getShare()->getTableName(), error);
1042
990
}
1043
991
 
1044
992
 
1051
999
  @return
1052
1000
    Returns true if this is a temporary error
1053
1001
*/
1054
 
bool StorageEngine::get_error_message(int , String* ) const
 
1002
bool StorageEngine::get_error_message(int , String* )
1055
1003
{
1056
1004
  return false;
1057
1005
}
1058
1006
 
1059
1007
 
1060
 
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, const Table &table) const
 
1008
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, Table &table)
1061
1009
{
1062
1010
  /* Write the duplicated key in the error message */
1063
1011
  char key[MAX_KEY_LENGTH];
1085
1033
}
1086
1034
 
1087
1035
 
1088
 
int StorageEngine::deleteDefinitionFromPath(const identifier::Table &identifier)
 
1036
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1089
1037
{
1090
 
  std::string path(identifier.getPath());
 
1038
  string path(identifier.getPath());
1091
1039
 
1092
1040
  path.append(DEFAULT_DEFINITION_FILE_EXT);
1093
1041
 
1094
1042
  return internal::my_delete(path.c_str(), MYF(0));
1095
1043
}
1096
1044
 
1097
 
int StorageEngine::renameDefinitionFromPath(const identifier::Table &dest, const identifier::Table &src)
 
1045
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1098
1046
{
1099
1047
  message::Table table_message;
1100
 
  std::string src_path(src.getPath());
1101
 
  std::string dest_path(dest.getPath());
 
1048
  string src_path(src.getPath());
 
1049
  string dest_path(dest.getPath());
1102
1050
 
1103
1051
  src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1104
1052
  dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1123
1071
  return error;
1124
1072
}
1125
1073
 
1126
 
int StorageEngine::writeDefinitionFromPath(const identifier::Table &identifier, message::Table &table_message)
 
1074
int StorageEngine::writeDefinitionFromPath(const TableIdentifier &identifier, message::Table &table_message)
1127
1075
{
1128
1076
  char definition_file_tmp[FN_REFLEN];
1129
 
  std::string file_name(identifier.getPath());
 
1077
  string file_name(identifier.getPath());
1130
1078
 
1131
1079
  file_name.append(DEFAULT_DEFINITION_FILE_EXT);
1132
1080
 
1145
1093
 
1146
1094
  bool success;
1147
1095
 
1148
 
  try
1149
 
  {
 
1096
  try {
1150
1097
    success= table_message.SerializeToZeroCopyStream(output);
1151
1098
  }
1152
1099
  catch (...)
1156
1103
 
1157
1104
  if (not success)
1158
1105
  {
1159
 
    std::string error_message;
1160
 
    identifier.getSQLPath(error_message);
1161
 
 
1162
1106
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1163
 
             error_message.c_str(),
1164
1107
             table_message.InitializationErrorString().c_str());
1165
1108
    delete output;
1166
1109
 
1200
1143
  return 0;
1201
1144
}
1202
1145
 
1203
 
class CanCreateTable: public std::unary_function<StorageEngine *, bool>
 
1146
class CanCreateTable: public unary_function<StorageEngine *, bool>
1204
1147
{
1205
 
  const identifier::Table &identifier;
 
1148
  const TableIdentifier &identifier;
1206
1149
 
1207
1150
public:
1208
 
  CanCreateTable(const identifier::Table &identifier_arg) :
 
1151
  CanCreateTable(const TableIdentifier &identifier_arg) :
1209
1152
    identifier(identifier_arg)
1210
1153
  { }
1211
1154
 
1219
1162
/**
1220
1163
  @note on success table can be created.
1221
1164
*/
1222
 
bool StorageEngine::canCreateTable(const identifier::Table &identifier)
 
1165
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1223
1166
{
1224
1167
  EngineVector::iterator iter=
1225
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1226
 
                 CanCreateTable(identifier));
 
1168
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
1169
            CanCreateTable(identifier));
1227
1170
 
1228
1171
  if (iter == vector_of_engines.end())
1229
1172
  {
1235
1178
 
1236
1179
bool StorageEngine::readTableFile(const std::string &path, message::Table &table_message)
1237
1180
{
1238
 
  std::fstream input(path.c_str(), std::ios::in | std::ios::binary);
 
1181
  fstream input(path.c_str(), ios::in | ios::binary);
1239
1182
 
1240
1183
  if (input.good())
1241
1184
  {
1248
1191
    catch (...)
1249
1192
    {
1250
1193
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1251
 
               table_message.name().empty() ? path.c_str() : table_message.name().c_str(),
1252
1194
               table_message.InitializationErrorString().empty() ? "": table_message.InitializationErrorString().c_str());
1253
1195
    }
1254
1196
  }
1260
1202
  return false;
1261
1203
}
1262
1204
 
1263
 
std::ostream& operator<<(std::ostream& output, const StorageEngine &engine)
1264
 
{
1265
 
  output << "StorageEngine:(";
1266
 
  output <<  engine.getName();
1267
 
  output << ")";
1268
1205
 
1269
 
  return output;
1270
 
}
1271
1206
 
1272
1207
} /* namespace plugin */
1273
1208
} /* namespace drizzled */