~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/storage_engine.cc

  • Committer: Brian Aker
  • Date: 2010-08-18 19:37:19 UTC
  • mto: This revision was merged to the branch mainline in revision 1720.
  • Revision ID: brian@tangent.org-20100818193719-bxxzn1pi22styowd
created function that can be used to simply crash the server.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
58
#include <boost/algorithm/string/compare.hpp>
62
59
 
63
60
static bool shutdown_has_begun= false; // Once we put in the container for the vector/etc for engines this will go away.
64
61
 
 
62
using namespace std;
 
63
 
65
64
namespace drizzled
66
65
{
67
66
 
82
81
  return vector_of_schema_engines;
83
82
}
84
83
 
85
 
StorageEngine::StorageEngine(const std::string name_arg,
86
 
                             const std::bitset<HTON_BIT_SIZE> &flags_arg) :
 
84
StorageEngine::StorageEngine(const string name_arg,
 
85
                             const bitset<HTON_BIT_SIZE> &flags_arg) :
87
86
  Plugin(name_arg, "StorageEngine"),
88
87
  MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
89
88
  flags(flags_arg)
192
191
}
193
192
 
194
193
class FindEngineByName
195
 
  : public std::unary_function<StorageEngine *, bool>
 
194
  : public unary_function<StorageEngine *, bool>
196
195
{
197
 
  const std::string &predicate;
 
196
  const string &predicate;
198
197
 
199
198
public:
200
 
  explicit FindEngineByName(const std::string &target_arg) :
 
199
  explicit FindEngineByName(const string &target_arg) :
201
200
    predicate(target_arg)
202
201
  {
203
202
  }
208
207
  }
209
208
};
210
209
 
211
 
StorageEngine *StorageEngine::findByName(const std::string &predicate)
 
210
StorageEngine *StorageEngine::findByName(const string &predicate)
212
211
{
213
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
214
 
                                            vector_of_engines.end(),
215
 
                                            FindEngineByName(predicate));
 
212
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
 
213
                                       vector_of_engines.end(),
 
214
                                       FindEngineByName(predicate));
216
215
  if (iter != vector_of_engines.end())
217
216
  {
218
217
    StorageEngine *engine= *iter;
223
222
  return NULL;
224
223
}
225
224
 
226
 
StorageEngine *StorageEngine::findByName(Session& session, const std::string &predicate)
 
225
StorageEngine *StorageEngine::findByName(Session& session, const string &predicate)
227
226
{
228
227
  if (boost::iequals(predicate, DEFAULT_STRING))
229
228
    return session.getDefaultStorageEngine();
230
229
 
231
 
  EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
232
 
                                            vector_of_engines.end(),
233
 
                                            FindEngineByName(predicate));
 
230
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
 
231
                                       vector_of_engines.end(),
 
232
                                       FindEngineByName(predicate));
234
233
  if (iter != vector_of_engines.end())
235
234
  {
236
235
    StorageEngine *engine= *iter;
241
240
  return NULL;
242
241
}
243
242
 
244
 
class StorageEngineCloseConnection : public std::unary_function<StorageEngine *, void>
 
243
class StorageEngineCloseConnection : public unary_function<StorageEngine *, void>
245
244
{
246
245
  Session *session;
247
246
public:
263
262
*/
264
263
void StorageEngine::closeConnection(Session* session)
265
264
{
266
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
267
 
                StorageEngineCloseConnection(session));
 
265
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
266
           StorageEngineCloseConnection(session));
268
267
}
269
268
 
270
269
bool StorageEngine::flushLogs(StorageEngine *engine)
271
270
{
272
271
  if (engine == NULL)
273
272
  {
274
 
    if (std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
 
                     std::mem_fun(&StorageEngine::flush_logs))
 
273
    if (find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
274
                mem_fun(&StorageEngine::flush_logs))
276
275
        != vector_of_engines.begin())
277
276
      return true;
278
277
  }
284
283
  return false;
285
284
}
286
285
 
287
 
class StorageEngineGetTableDefinition: public std::unary_function<StorageEngine *,bool>
 
286
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
288
287
{
289
288
  Session& session;
290
289
  const TableIdentifier &identifier;
312
311
  }
313
312
};
314
313
 
315
 
class StorageEngineDoesTableExist: public std::unary_function<StorageEngine *, bool>
 
314
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
316
315
{
317
316
  Session& session;
318
317
  const TableIdentifier &identifier;
343
342
  }
344
343
 
345
344
  EngineVector::iterator iter=
346
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
347
 
                 StorageEngineDoesTableExist(session, identifier));
 
345
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
346
            StorageEngineDoesTableExist(session, identifier));
348
347
 
349
348
  if (iter == vector_of_engines.end())
350
349
  {
356
355
 
357
356
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::TableIdentifier&)
358
357
{
359
 
  std::cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
 
358
  cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
360
359
  assert(0);
361
360
  return false;
362
361
}
368
367
*/
369
368
int StorageEngine::getTableDefinition(Session& session,
370
369
                                      const TableIdentifier &identifier,
371
 
                                      message::table::shared_ptr &table_message,
 
370
                                      message::Table &table_message,
372
371
                                      bool include_temporary_tables)
373
372
{
374
373
  int err= ENOENT;
375
374
 
376
375
  if (include_temporary_tables)
377
376
  {
378
 
    Table *table= session.find_temporary_table(identifier);
379
 
    if (table)
380
 
    {
381
 
      table_message.reset(new message::Table(*table->getShare()->getTableProto()));
 
377
    if (session.doGetTableDefinition(identifier, table_message) == EEXIST)
382
378
      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;
 
379
  }
 
380
 
393
381
  EngineVector::iterator iter=
394
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
395
 
                 StorageEngineGetTableDefinition(session, identifier, message, err));
 
382
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
383
            StorageEngineGetTableDefinition(session, identifier, table_message, err));
396
384
 
397
385
  if (iter == vector_of_engines.end())
398
386
  {
399
387
    return ENOENT;
400
388
  }
401
 
  table_message.reset(new message::Table(message));
402
 
 
403
 
 drizzled::message::Cache::singleton().insert(identifier, table_message);
404
389
 
405
390
  return err;
406
391
}
443
428
{
444
429
  int error= 0;
445
430
  int error_proto;
446
 
  message::table::shared_ptr src_proto;
 
431
  message::Table src_proto;
447
432
  StorageEngine *engine;
448
433
 
449
434
  error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
450
435
 
451
436
  if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
452
437
  {
453
 
    std::string error_message;
454
 
    identifier.getSQLPath(error_message);
 
438
    string error_message;
455
439
 
 
440
    error_message.append(const_cast<TableIdentifier &>(identifier).getSQLPath());
456
441
    error_message.append(" : ");
457
 
    error_message.append(src_proto->InitializationErrorString());
 
442
    error_message.append(src_proto.InitializationErrorString());
458
443
 
459
444
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
460
445
 
461
446
    return ER_CORRUPT_TABLE_DEFINITION;
462
447
  }
463
448
 
464
 
  if (src_proto)
465
 
    engine= StorageEngine::findByName(session, src_proto->engine().name());
466
 
  else
467
 
    engine= StorageEngine::findByName(session, "");
 
449
  engine= StorageEngine::findByName(session, src_proto.engine().name());
468
450
 
469
451
  if (not engine)
470
452
  {
471
 
    std::string error_message;
472
 
    identifier.getSQLPath(error_message);
473
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
 
453
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str());
474
454
 
475
455
    return ER_CORRUPT_TABLE_DEFINITION;
476
456
  }
504
484
    }
505
485
  }
506
486
 
507
 
  drizzled::message::Cache::singleton().erase(identifier);
508
487
 
509
488
  return error;
510
489
}
523
502
                               message::Table& table_message)
524
503
{
525
504
  int error= 1;
 
505
  Table table;
526
506
  TableShare share(identifier);
527
 
  table::Shell table(share);
528
507
  message::Table tmp_proto;
529
508
 
530
509
  if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
556
535
 
557
536
    if (error)
558
537
    {
559
 
      std::string path;
560
 
      identifier.getSQLPath(path);
561
 
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), path.c_str(), error);
 
538
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
562
539
    }
563
540
 
564
541
    table.delete_table();
567
544
  return(error != 0);
568
545
}
569
546
 
570
 
Cursor *StorageEngine::getCursor(Table &arg)
 
547
Cursor *StorageEngine::getCursor(TableShare &share)
571
548
{
572
 
  return create(arg);
 
549
  return create(share);
573
550
}
574
551
 
575
552
class AddTableIdentifier : 
576
 
  public std::unary_function<StorageEngine *, void>
 
553
  public unary_function<StorageEngine *, void>
577
554
{
578
555
  CachedDirectory &directory;
579
556
  const SchemaIdentifier &identifier;
580
 
  TableIdentifier::vector &set_of_identifiers;
 
557
  TableIdentifiers &set_of_identifiers;
581
558
 
582
559
public:
583
560
 
584
 
  AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifier::vector &of_names) :
 
561
  AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
585
562
    directory(directory_arg),
586
563
    identifier(identifier_arg),
587
564
    set_of_identifiers(of_names)
595
572
};
596
573
 
597
574
 
598
 
void StorageEngine::getIdentifiers(Session &session, const SchemaIdentifier &schema_identifier, TableIdentifier::vector &set_of_identifiers)
 
575
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
 
576
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
 
577
 
 
578
void StorageEngine::getIdentifiers(Session &session, const SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
599
579
{
600
 
  static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
601
 
  static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
602
 
 
603
580
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
604
581
 
605
582
  if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
612
589
    {
613
590
      errno= directory.getError();
614
591
      if (errno == ENOENT)
615
 
      {
616
 
        std::string path;
617
 
        schema_identifier.getSQLPath(path);
618
 
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), path.c_str());
619
 
      }
 
592
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), const_cast<SchemaIdentifier &>(schema_identifier).getSQLPath().c_str());
620
593
      else
621
 
      {
622
594
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
623
 
      }
624
 
 
625
595
      return;
626
596
    }
627
597
  }
628
598
 
629
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
630
 
                AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
 
599
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
600
           AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
631
601
 
632
602
  session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
633
603
}
634
604
 
635
 
class DropTable: public std::unary_function<TableIdentifier&, bool>
 
605
class DropTable: public unary_function<TableIdentifier&, bool>
636
606
{
637
607
  Session &session;
638
608
  StorageEngine *engine;
651
621
};
652
622
 
653
623
/* This will later be converted to TableIdentifiers */
654
 
class DropTables: public std::unary_function<StorageEngine *, void>
 
624
class DropTables: public unary_function<StorageEngine *, void>
655
625
{
656
626
  Session &session;
657
 
  TableIdentifier::vector &table_identifiers;
 
627
  TableIdentifiers &table_identifiers;
658
628
 
659
629
public:
660
630
 
661
 
  DropTables(Session &session_arg, TableIdentifier::vector &table_identifiers_arg) :
 
631
  DropTables(Session &session_arg, TableIdentifiers &table_identifiers_arg) :
662
632
    session(session_arg),
663
633
    table_identifiers(table_identifiers_arg)
664
634
  { }
667
637
  {
668
638
    // True returning from DropTable means the table has been successfully
669
639
    // deleted, so it should be removed from the list of tables to drop
670
 
    table_identifiers.erase(std::remove_if(table_identifiers.begin(),
671
 
                                           table_identifiers.end(),
672
 
                                           DropTable(session, engine)),
 
640
    table_identifiers.erase(remove_if(table_identifiers.begin(),
 
641
                                      table_identifiers.end(),
 
642
                                      DropTable(session, engine)),
673
643
                            table_identifiers.end());
674
644
  }
675
645
};
682
652
void StorageEngine::removeLostTemporaryTables(Session &session, const char *directory)
683
653
{
684
654
  CachedDirectory dir(directory, set_of_table_definition_ext);
685
 
  TableIdentifier::vector table_identifiers;
 
655
  TableIdentifiers table_identifiers;
686
656
 
687
657
  if (dir.fail())
688
658
  {
698
668
       fileIter != files.end(); fileIter++)
699
669
  {
700
670
    size_t length;
701
 
    std::string path;
 
671
    string path;
702
672
    CachedDirectory::Entry *entry= *fileIter;
703
673
 
704
674
    /* We remove the file extension. */
716
686
    }
717
687
  }
718
688
 
719
 
  std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
720
 
                DropTables(session, table_identifiers));
721
 
 
 
689
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
 
690
           DropTables(session, table_identifiers));
 
691
  
722
692
  /*
723
693
    Now we just clean up anything that might left over.
724
694
 
725
695
    We rescan because some of what might have been there should
726
696
    now be all nice and cleaned up.
727
697
  */
728
 
  std::set<std::string> all_exts= set_of_table_definition_ext;
 
698
  set<string> all_exts= set_of_table_definition_ext;
729
699
 
730
700
  for (EngineVector::iterator iter= vector_of_engines.begin();
731
701
       iter != vector_of_engines.end() ; iter++)
740
710
  for (CachedDirectory::Entries::iterator fileIter= files.begin();
741
711
       fileIter != files.end(); fileIter++)
742
712
  {
743
 
    std::string path;
 
713
    string path;
744
714
    CachedDirectory::Entry *entry= *fileIter;
745
715
 
746
716
    path+= directory;
1007
977
 
1008
978
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1009
979
{
1010
 
  std::string path(identifier.getPath());
 
980
  string path(identifier.getPath());
1011
981
 
1012
982
  path.append(DEFAULT_DEFINITION_FILE_EXT);
1013
983
 
1017
987
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1018
988
{
1019
989
  message::Table table_message;
1020
 
  std::string src_path(src.getPath());
1021
 
  std::string dest_path(dest.getPath());
 
990
  string src_path(src.getPath());
 
991
  string dest_path(dest.getPath());
1022
992
 
1023
993
  src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1024
994
  dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1046
1016
int StorageEngine::writeDefinitionFromPath(const TableIdentifier &identifier, message::Table &table_message)
1047
1017
{
1048
1018
  char definition_file_tmp[FN_REFLEN];
1049
 
  std::string file_name(identifier.getPath());
 
1019
  string file_name(identifier.getPath());
1050
1020
 
1051
1021
  file_name.append(DEFAULT_DEFINITION_FILE_EXT);
1052
1022
 
1065
1035
 
1066
1036
  bool success;
1067
1037
 
1068
 
  try
1069
 
  {
 
1038
  try {
1070
1039
    success= table_message.SerializeToZeroCopyStream(output);
1071
1040
  }
1072
1041
  catch (...)
1116
1085
  return 0;
1117
1086
}
1118
1087
 
1119
 
class CanCreateTable: public std::unary_function<StorageEngine *, bool>
 
1088
class CanCreateTable: public unary_function<StorageEngine *, bool>
1120
1089
{
1121
1090
  const TableIdentifier &identifier;
1122
1091
 
1138
1107
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1139
1108
{
1140
1109
  EngineVector::iterator iter=
1141
 
    std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1142
 
                 CanCreateTable(identifier));
 
1110
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
 
1111
            CanCreateTable(identifier));
1143
1112
 
1144
1113
  if (iter == vector_of_engines.end())
1145
1114
  {
1151
1120
 
1152
1121
bool StorageEngine::readTableFile(const std::string &path, message::Table &table_message)
1153
1122
{
1154
 
  std::fstream input(path.c_str(), std::ios::in | std::ios::binary);
 
1123
  fstream input(path.c_str(), ios::in | ios::binary);
1155
1124
 
1156
1125
  if (input.good())
1157
1126
  {