~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-03 04:19:05 UTC
  • mto: This revision was merged to the branch mainline in revision 1684.
  • Revision ID: brian@gaz-20100803041905-xkgqsndtrqf2xetg
Remove call for using special new for a cursor.

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
#include "drizzled/db.h"
54
54
 
55
55
#include <drizzled/table_proto.h>
 
56
#include <drizzled/plugin/event_observer.h>
56
57
 
57
58
static bool shutdown_has_begun= false; // Once we put in the container for the vector/etc for engines this will go away.
58
59
 
96
97
}
97
98
 
98
99
 
99
 
int StorageEngine::renameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
 
100
int StorageEngine::renameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
100
101
{
 
102
  int error;
101
103
  setTransactionReadWrite(session);
102
104
 
103
 
  return doRenameTable(session, from, to);
 
105
  if (unlikely(plugin::EventObserver::beforeRenameTable(session, from, to)))
 
106
  {
 
107
    error= ER_EVENT_OBSERVER_PLUGIN;
 
108
  }
 
109
  else
 
110
  {
 
111
    error =  doRenameTable(session, from, to);
 
112
    if (unlikely(plugin::EventObserver::afterRenameTable(session, from, to, error)))
 
113
    {
 
114
      error= ER_EVENT_OBSERVER_PLUGIN;
 
115
    }
 
116
  }
 
117
  
 
118
  return error;
104
119
}
105
120
 
106
121
/**
118
133
  @retval
119
134
    !0  Error
120
135
*/
121
 
int StorageEngine::doDropTable(Session&, TableIdentifier &identifier)
 
136
int StorageEngine::doDropTable(Session&, const TableIdentifier &identifier)
122
137
                               
123
138
{
124
139
  int error= 0;
280
295
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
281
296
{
282
297
  Session& session;
283
 
  TableIdentifier &identifier;
 
298
  const TableIdentifier &identifier;
284
299
  message::Table &table_message;
285
300
  int &err;
286
301
 
287
302
public:
288
303
  StorageEngineGetTableDefinition(Session& session_arg,
289
 
                                  TableIdentifier &identifier_arg,
 
304
                                  const TableIdentifier &identifier_arg,
290
305
                                  message::Table &table_message_arg,
291
306
                                  int &err_arg) :
292
307
    session(session_arg), 
308
323
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
309
324
{
310
325
  Session& session;
311
 
  TableIdentifier &identifier;
 
326
  const TableIdentifier &identifier;
312
327
 
313
328
public:
314
 
  StorageEngineDoesTableExist(Session& session_arg, TableIdentifier &identifier_arg) :
 
329
  StorageEngineDoesTableExist(Session& session_arg, const TableIdentifier &identifier_arg) :
315
330
    session(session_arg), 
316
331
    identifier(identifier_arg) 
317
332
  { }
326
341
  Utility method which hides some of the details of getTableDefinition()
327
342
*/
328
343
bool plugin::StorageEngine::doesTableExist(Session &session,
329
 
                                           TableIdentifier &identifier,
 
344
                                           const TableIdentifier &identifier,
330
345
                                           bool include_temporary_tables)
331
346
{
332
347
  if (include_temporary_tables)
347
362
  return true;
348
363
}
349
364
 
350
 
bool plugin::StorageEngine::doDoesTableExist(Session&, TableIdentifier&)
 
365
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::TableIdentifier&)
351
366
{
352
367
  cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
353
368
  assert(0);
360
375
  or any dropped tables that need to be removed from disk
361
376
*/
362
377
int StorageEngine::getTableDefinition(Session& session,
363
 
                                      TableIdentifier &identifier,
 
378
                                      const TableIdentifier &identifier,
364
379
                                      message::Table &table_message,
365
380
                                      bool include_temporary_tables)
366
381
{
418
433
   returns ENOENT if the file doesn't exists.
419
434
*/
420
435
int StorageEngine::dropTable(Session& session,
421
 
                             TableIdentifier &identifier)
 
436
                             const TableIdentifier &identifier)
422
437
{
423
438
  int error= 0;
424
439
  int error_proto;
431
446
  {
432
447
    string error_message;
433
448
 
434
 
    error_message.append(identifier.getSQLPath());
 
449
    error_message.append(const_cast<TableIdentifier &>(identifier).getSQLPath());
435
450
    error_message.append(" : ");
436
451
    error_message.append(src_proto.InitializationErrorString());
437
452
 
444
459
 
445
460
  if (not engine)
446
461
  {
447
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), identifier.getSQLPath().c_str());
 
462
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str());
448
463
 
449
464
    return ER_CORRUPT_TABLE_DEFINITION;
450
465
  }
459
474
 
460
475
int StorageEngine::dropTable(Session& session,
461
476
                             StorageEngine &engine,
462
 
                             TableIdentifier &identifier)
 
477
                             const TableIdentifier &identifier)
463
478
{
464
479
  int error;
465
480
 
466
481
  engine.setTransactionReadWrite(session);
467
 
  error= engine.doDropTable(session, identifier);
 
482
  
 
483
  if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
 
484
  {
 
485
    error= ER_EVENT_OBSERVER_PLUGIN;
 
486
  }
 
487
  else
 
488
  {
 
489
    error= engine.doDropTable(session, identifier);
 
490
    if (unlikely(plugin::EventObserver::afterDropTable(session, identifier, error)))
 
491
    {
 
492
      error= ER_EVENT_OBSERVER_PLUGIN;
 
493
    }
 
494
  }
 
495
 
468
496
 
469
497
  return error;
470
498
}
479
507
   1  error
480
508
*/
481
509
int StorageEngine::createTable(Session &session,
482
 
                               TableIdentifier &identifier,
483
 
                               bool update_create_info,
 
510
                               const TableIdentifier &identifier,
484
511
                               message::Table& table_message)
485
512
{
486
513
  int error= 1;
487
514
  Table table;
488
 
  TableShare share(identifier.getSchemaName().c_str(), 0, identifier.getTableName().c_str(), identifier.getPath().c_str());
 
515
  TableShare share(identifier);
489
516
  message::Table tmp_proto;
490
517
 
491
 
  if (parse_table_proto(session, table_message, &share) || open_table_from_share(&session, &share, "", 0, 0, &table))
 
518
  if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
492
519
  { 
493
520
    // @note Error occured, we should probably do a little more here.
494
521
  }
495
522
  else
496
523
  {
497
 
    if (update_create_info)
498
 
      table.updateCreateInfo(&table_message);
499
 
 
500
524
    /* Check for legal operations against the Engine using the proto (if used) */
501
525
    if (table_message.type() == message::Table::TEMPORARY &&
502
526
        share.storage_engine->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED) == true)
520
544
 
521
545
    if (error)
522
546
    {
523
 
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), identifier.getSQLPath().c_str(), error);
 
547
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
524
548
    }
525
549
 
526
 
    table.closefrm(false);
 
550
    table.delete_table();
527
551
  }
528
552
 
529
 
  share.free_table_share();
530
553
  return(error != 0);
531
554
}
532
555
 
533
 
Cursor *StorageEngine::getCursor(TableShare &share, memory::Root *alloc)
 
556
Cursor *StorageEngine::getCursor(TableShare &share)
534
557
{
535
 
  return create(share, alloc);
 
558
  return create(share);
536
559
}
537
560
 
538
 
class AddTableName : 
539
 
  public unary_function<StorageEngine *, void>
540
 
{
541
 
  CachedDirectory &directory;
542
 
  SchemaIdentifier &identifier;
543
 
  TableNameList &set_of_names;
544
 
 
545
 
public:
546
 
 
547
 
  AddTableName(CachedDirectory &directory_arg, SchemaIdentifier &identifier_arg, set<string>& of_names) :
548
 
    directory(directory_arg),
549
 
    identifier(identifier_arg),
550
 
    set_of_names(of_names)
551
 
  {
552
 
  }
553
 
 
554
 
  result_type operator() (argument_type engine)
555
 
  {
556
 
    engine->doGetTableNames(directory, identifier, set_of_names);
557
 
  }
558
 
};
559
 
 
560
561
class AddTableIdentifier : 
561
562
  public unary_function<StorageEngine *, void>
562
563
{
563
564
  CachedDirectory &directory;
564
 
  SchemaIdentifier &identifier;
 
565
  const SchemaIdentifier &identifier;
565
566
  TableIdentifiers &set_of_identifiers;
566
567
 
567
568
public:
568
569
 
569
 
  AddTableIdentifier(CachedDirectory &directory_arg, SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
 
570
  AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
570
571
    directory(directory_arg),
571
572
    identifier(identifier_arg),
572
573
    set_of_identifiers(of_names)
583
584
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
584
585
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
585
586
 
586
 
void StorageEngine::getTableNames(Session &session, SchemaIdentifier &schema_identifier, TableNameList &set_of_names)
587
 
{
588
 
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
589
 
 
590
 
  if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
591
 
  { }
592
 
  else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
593
 
  { }
594
 
  else
595
 
  {
596
 
    if (directory.fail())
597
 
    {
598
 
      errno= directory.getError();
599
 
      if (errno == ENOENT)
600
 
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
601
 
      else
602
 
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
603
 
      return;
604
 
    }
605
 
  }
606
 
 
607
 
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
608
 
           AddTableName(directory, schema_identifier, set_of_names));
609
 
 
610
 
  session.doGetTableNames(directory, schema_identifier, set_of_names);
611
 
}
612
 
 
613
 
void StorageEngine::getTableIdentifiers(Session &session, SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
614
 
{
615
 
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
616
 
 
617
 
  if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
618
 
  { }
619
 
  else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
620
 
  { }
621
 
  else
622
 
  {
623
 
    if (directory.fail())
624
 
    {
625
 
      errno= directory.getError();
626
 
      if (errno == ENOENT)
627
 
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
 
587
void StorageEngine::getIdentifiers(Session &session, const SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
 
588
{
 
589
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
 
590
 
 
591
  if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
 
592
  { }
 
593
  else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
 
594
  { }
 
595
  else
 
596
  {
 
597
    if (directory.fail())
 
598
    {
 
599
      errno= directory.getError();
 
600
      if (errno == ENOENT)
 
601
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), const_cast<SchemaIdentifier &>(schema_identifier).getSQLPath().c_str());
628
602
      else
629
603
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
630
604
      return;
637
611
  session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
638
612
}
639
613
 
 
614
class DropTable: public unary_function<TableIdentifier&, bool>
 
615
{
 
616
  Session &session;
 
617
  StorageEngine *engine;
 
618
 
 
619
public:
 
620
 
 
621
  DropTable(Session &session_arg, StorageEngine *engine_arg) :
 
622
    session(session_arg),
 
623
    engine(engine_arg)
 
624
  { }
 
625
 
 
626
  result_type operator() (argument_type identifier)
 
627
  {
 
628
    return engine->doDropTable(session, identifier) == 0;
 
629
  } 
 
630
};
 
631
 
640
632
/* This will later be converted to TableIdentifiers */
641
633
class DropTables: public unary_function<StorageEngine *, void>
642
634
{
643
635
  Session &session;
644
 
  TableIdentifierList &table_identifiers;
 
636
  TableIdentifiers &table_identifiers;
645
637
 
646
638
public:
647
639
 
648
 
  DropTables(Session &session_arg, TableIdentifierList &table_identifiers_arg) :
 
640
  DropTables(Session &session_arg, TableIdentifiers &table_identifiers_arg) :
649
641
    session(session_arg),
650
642
    table_identifiers(table_identifiers_arg)
651
643
  { }
652
644
 
653
645
  result_type operator() (argument_type engine)
654
646
  {
655
 
    for (TableIdentifierList::iterator iter= table_identifiers.begin();
656
 
         iter != table_identifiers.end();
657
 
         iter++)
658
 
    {
659
 
      int error= engine->doDropTable(session, const_cast<TableIdentifier&>(*iter));
660
 
 
661
 
      // On a return of zero we know we found and deleted the table. So we
662
 
      // remove it from our search.
663
 
      if (not error)
664
 
        table_identifiers.erase(iter);
665
 
    }
 
647
    // True returning from DropTable means the table has been successfully
 
648
    // deleted, so it should be removed from the list of tables to drop
 
649
    table_identifiers.erase(remove_if(table_identifiers.begin(),
 
650
                                      table_identifiers.end(),
 
651
                                      DropTable(session, engine)),
 
652
                            table_identifiers.end());
666
653
  }
667
654
};
668
655
 
674
661
void StorageEngine::removeLostTemporaryTables(Session &session, const char *directory)
675
662
{
676
663
  CachedDirectory dir(directory, set_of_table_definition_ext);
677
 
  TableIdentifierList table_identifiers;
 
664
  TableIdentifiers table_identifiers;
678
665
 
679
666
  if (dir.fail())
680
667
  {
750
737
  @note
751
738
    In case of delete table it's only safe to use the following parts of
752
739
    the 'table' structure:
753
 
    - table->s->path
 
740
    - table->getShare()->path
754
741
    - table->alias
755
742
*/
756
743
void StorageEngine::print_error(int error, myf errflag, Table &table)
787
774
    {
788
775
      const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
789
776
 
790
 
      if (key_nr == 0 &&
791
 
          (table->key_info[0].key_part[0].field->flags &
792
 
           AUTO_INCREMENT_FLAG)
793
 
          && (current_session)->lex->sql_command == SQLCOM_ALTER_TABLE)
794
 
      {
795
 
        err_msg= ER(ER_DUP_ENTRY_AUTOINCREMENT_CASE);
796
 
      }
797
 
 
798
777
      print_keydup_error(key_nr, err_msg, *table);
 
778
 
799
779
      return;
800
780
    }
801
781
    textno=ER_DUP_KEY;
822
802
        str.length(max_length-4);
823
803
        str.append(STRING_WITH_LEN("..."));
824
804
      }
825
 
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table->s->table_name.str,
 
805
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table->getShare()->getTableName(),
826
806
        str.c_ptr(), key_nr+1);
827
807
      return;
828
808
    }
900
880
    break;
901
881
  case HA_ERR_NO_SUCH_TABLE:
902
882
    assert(table);
903
 
    my_error(ER_NO_SUCH_TABLE, MYF(0), table->s->getSchemaName(),
904
 
             table->s->table_name.str);
 
883
    my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
 
884
             table->getShare()->getTableName());
905
885
    return;
906
886
  case HA_ERR_RBR_LOGGING_FAILED:
907
887
    textno= ER_BINLOG_ROW_LOGGING_FAILED;
957
937
      return;
958
938
    }
959
939
  }
960
 
  my_error(textno, errflag, table->s->table_name.str, error);
 
940
  my_error(textno, errflag, table->getShare()->getTableName(), error);
961
941
}
962
942
 
963
943
 
1004
984
}
1005
985
 
1006
986
 
1007
 
int StorageEngine::deleteDefinitionFromPath(TableIdentifier &identifier)
 
987
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1008
988
{
1009
989
  string path(identifier.getPath());
1010
990
 
1013
993
  return internal::my_delete(path.c_str(), MYF(0));
1014
994
}
1015
995
 
1016
 
int StorageEngine::renameDefinitionFromPath(TableIdentifier &dest, TableIdentifier &src)
 
996
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1017
997
{
1018
998
  message::Table table_message;
1019
999
  string src_path(src.getPath());
1042
1022
  return error;
1043
1023
}
1044
1024
 
1045
 
int StorageEngine::writeDefinitionFromPath(TableIdentifier &identifier, message::Table &table_message)
 
1025
int StorageEngine::writeDefinitionFromPath(const TableIdentifier &identifier, message::Table &table_message)
1046
1026
{
1047
1027
  char definition_file_tmp[FN_REFLEN];
1048
1028
  string file_name(identifier.getPath());
1062
1042
  google::protobuf::io::ZeroCopyOutputStream* output=
1063
1043
    new google::protobuf::io::FileOutputStream(fd);
1064
1044
 
1065
 
  if (not table_message.SerializeToZeroCopyStream(output))
 
1045
  bool success;
 
1046
 
 
1047
  try {
 
1048
    success= table_message.SerializeToZeroCopyStream(output);
 
1049
  }
 
1050
  catch (...)
 
1051
  {
 
1052
    success= false;
 
1053
  }
 
1054
 
 
1055
  if (not success)
1066
1056
  {
1067
1057
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1068
1058
             table_message.InitializationErrorString().c_str());
1106
1096
 
1107
1097
class CanCreateTable: public unary_function<StorageEngine *, bool>
1108
1098
{
1109
 
  TableIdentifier &identifier;
 
1099
  const TableIdentifier &identifier;
1110
1100
 
1111
1101
public:
1112
 
  CanCreateTable(TableIdentifier &identifier_arg) :
 
1102
  CanCreateTable(const TableIdentifier &identifier_arg) :
1113
1103
    identifier(identifier_arg)
1114
1104
  { }
1115
1105
 
1123
1113
/**
1124
1114
  @note on success table can be created.
1125
1115
*/
1126
 
bool StorageEngine::canCreateTable(drizzled::TableIdentifier &identifier)
 
1116
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1127
1117
{
1128
1118
  EngineVector::iterator iter=
1129
1119
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
1143
1133
 
1144
1134
  if (input.good())
1145
1135
  {
1146
 
    if (table_message.ParseFromIstream(&input))
 
1136
    try {
 
1137
      if (table_message.ParseFromIstream(&input))
 
1138
      {
 
1139
        return true;
 
1140
      }
 
1141
    }
 
1142
    catch (...)
1147
1143
    {
1148
 
      return true;
 
1144
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
 
1145
               table_message.InitializationErrorString().empty() ? "": table_message.InitializationErrorString().c_str());
1149
1146
    }
1150
 
 
1151
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1152
 
             table_message.InitializationErrorString().c_str());
1153
1147
  }
1154
1148
  else
1155
1149
  {