506
@todo refactor to remove goto
481
int StorageEngine::createTable(Session &session,
508
int StorageEngine::createTable(Session& session,
482
509
TableIdentifier &identifier,
483
510
bool update_create_info,
484
511
message::Table& table_message)
488
TableShare share(identifier.getSchemaName().c_str(), 0, identifier.getTableName().c_str(), identifier.getPath().c_str());
515
TableShare share(identifier.getDBName().c_str(), 0, identifier.getTableName().c_str(), identifier.getPath().c_str());
489
516
message::Table tmp_proto;
491
if (parse_table_proto(session, table_message, &share) || open_table_from_share(&session, &share, "", 0, 0, &table))
493
// @note Error occured, we should probably do a little more here.
497
if (update_create_info)
498
table.updateCreateInfo(&table_message);
500
/* Check for legal operations against the Engine using the proto (if used) */
501
if (table_message.type() == message::Table::TEMPORARY &&
502
share.storage_engine->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED) == true)
504
error= HA_ERR_UNSUPPORTED;
506
else if (table_message.type() != message::Table::TEMPORARY &&
507
share.storage_engine->check_flag(HTON_BIT_TEMPORARY_ONLY) == true)
509
error= HA_ERR_UNSUPPORTED;
513
share.storage_engine->setTransactionReadWrite(session);
515
error= share.storage_engine->doCreateTable(session,
523
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), identifier.getSQLPath().c_str(), error);
526
table.closefrm(false);
518
if (parse_table_proto(session, table_message, &share))
521
if (open_table_from_share(&session, &share, "", 0, 0,
525
if (update_create_info)
526
table.updateCreateInfo(&table_message);
528
/* Check for legal operations against the Engine using the proto (if used) */
529
if (table_message.type() == message::Table::TEMPORARY &&
530
share.storage_engine->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED) == true)
532
error= HA_ERR_UNSUPPORTED;
535
else if (table_message.type() != message::Table::TEMPORARY &&
536
share.storage_engine->check_flag(HTON_BIT_TEMPORARY_ONLY) == true)
538
error= HA_ERR_UNSUPPORTED;
543
if (not share.storage_engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
545
int protoerr= StorageEngine::writeDefinitionFromPath(identifier, table_message);
554
share.storage_engine->setTransactionReadWrite(session);
556
error= share.storage_engine->doCreateTable(&session,
565
if (not share.storage_engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
566
plugin::StorageEngine::deleteDefinitionFromPath(identifier);
568
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), identifier.getSQLPath().c_str(), error);
571
table.closefrm(false);
529
574
share.free_table_share();
530
575
return(error != 0);
535
580
return create(share, alloc);
584
TODO -> Remove this to force all engines to implement their own file. Solves the "we only looked at dfe" problem.
586
void StorageEngine::doGetTableNames(CachedDirectory&, string&, set<string>&)
538
589
class AddTableName :
539
590
public unary_function<StorageEngine *, void>
541
CachedDirectory &directory;
542
SchemaIdentifier &identifier;
593
CachedDirectory& directory;
543
594
TableNameList &set_of_names;
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)
554
result_type operator() (argument_type engine)
556
engine->doGetTableNames(directory, identifier, set_of_names);
560
class AddTableIdentifier :
561
public unary_function<StorageEngine *, void>
563
CachedDirectory &directory;
564
SchemaIdentifier &identifier;
565
TableIdentifiers &set_of_identifiers;
569
AddTableIdentifier(CachedDirectory &directory_arg, SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
570
directory(directory_arg),
571
identifier(identifier_arg),
572
set_of_identifiers(of_names)
576
result_type operator() (argument_type engine)
578
engine->doGetTableIdentifiers(directory, identifier, set_of_identifiers);
583
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
584
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
586
void StorageEngine::getTableNames(Session &session, SchemaIdentifier &schema_identifier, TableNameList &set_of_names)
588
CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
590
if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
592
else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
596
if (directory.fail())
598
errno= directory.getError();
600
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
602
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
607
for_each(vector_of_engines.begin(), vector_of_engines.end(),
608
AddTableName(directory, schema_identifier, set_of_names));
610
session.doGetTableNames(directory, schema_identifier, set_of_names);
613
void StorageEngine::getTableIdentifiers(Session &session, SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
615
CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
617
if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
619
else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
623
if (directory.fail())
625
errno= directory.getError();
627
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
629
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
634
for_each(vector_of_engines.begin(), vector_of_engines.end(),
635
AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
637
session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
598
AddTableName(CachedDirectory& directory_arg, const string& database_name, set<string>& of_names) :
599
directory(directory_arg),
600
set_of_names(of_names)
605
result_type operator() (argument_type engine)
607
engine->doGetTableNames(directory, db, set_of_names);
611
class AddSchemaNames :
612
public unary_function<StorageEngine *, void>
614
SchemaNameList &set_of_names;
618
AddSchemaNames(set<string>& of_names) :
619
set_of_names(of_names)
623
result_type operator() (argument_type engine)
625
engine->doGetSchemaNames(set_of_names);
629
void StorageEngine::getSchemaNames(SchemaNameList &set_of_names)
631
// Add hook here for engines to register schema.
632
for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
633
AddSchemaNames(set_of_names));
635
plugin::Authorization::pruneSchemaNames(current_session->getSecurityContext(),
639
class StorageEngineGetSchemaDefinition: public unary_function<StorageEngine *, bool>
641
const std::string &schema_name;
642
message::Schema &schema_proto;
645
StorageEngineGetSchemaDefinition(const std::string &schema_name_arg,
646
message::Schema &schema_proto_arg) :
647
schema_name(schema_name_arg),
648
schema_proto(schema_proto_arg)
651
result_type operator() (argument_type engine)
653
return engine->doGetSchemaDefinition(schema_name, schema_proto);
658
Return value is "if parsed"
660
bool StorageEngine::getSchemaDefinition(const std::string &schema_name, message::Schema &proto)
664
EngineVector::iterator iter=
665
find_if(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
666
StorageEngineGetSchemaDefinition(schema_name, proto));
668
if (iter != vector_of_schema_engines.end())
676
bool StorageEngine::doesSchemaExist(const std::string &schema_name)
678
message::Schema proto;
680
return StorageEngine::getSchemaDefinition(schema_name, proto);
684
const CHARSET_INFO *StorageEngine::getSchemaCollation(const std::string &schema_name)
686
message::Schema schmema_proto;
689
found= StorageEngine::getSchemaDefinition(schema_name, schmema_proto);
691
if (found && schmema_proto.has_collation())
693
const string buffer= schmema_proto.collation();
694
const CHARSET_INFO* cs= get_charset_by_name(buffer.c_str());
698
errmsg_printf(ERRMSG_LVL_ERROR,
699
_("Error while loading database options: '%s':"), schema_name.c_str());
700
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
702
return default_charset_info;
708
return default_charset_info;
712
public unary_function<StorageEngine *, void>
714
const drizzled::message::Schema &schema_message;
718
CreateSchema(const drizzled::message::Schema &arg) :
723
result_type operator() (argument_type engine)
725
// @todo eomeday check that at least one engine said "true"
726
(void)engine->doCreateSchema(schema_message);
730
bool StorageEngine::createSchema(const drizzled::message::Schema &schema_message)
732
// Add hook here for engines to register schema.
733
for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
734
CreateSchema(schema_message));
740
public unary_function<StorageEngine *, void>
742
uint64_t &success_count;
743
const string &schema_name;
747
DropSchema(const string &arg, uint64_t &count_arg) :
748
success_count(count_arg),
753
result_type operator() (argument_type engine)
755
// @todo someday check that at least one engine said "true"
756
bool success= engine->doDropSchema(schema_name);
763
bool StorageEngine::dropSchema(const string &schema_name)
766
// Add hook here for engines to register schema.
767
for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
768
DropSchema(schema_name, counter));
770
return counter ? true : false;
774
public unary_function<StorageEngine *, void>
776
uint64_t &success_count;
777
const drizzled::message::Schema &schema_message;
781
AlterSchema(const drizzled::message::Schema &arg, uint64_t &count_arg) :
782
success_count(count_arg),
787
result_type operator() (argument_type engine)
789
// @todo eomeday check that at least one engine said "true"
790
bool success= engine->doAlterSchema(schema_message);
797
bool StorageEngine::alterSchema(const drizzled::message::Schema &schema_message)
799
uint64_t success_count= 0;
801
for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
802
AlterSchema(schema_message, success_count));
804
return success_count ? true : false;
808
void StorageEngine::getTableNames(const string &schema_name, TableNameList &set_of_names)
812
build_table_filename(tmp_path, schema_name.c_str(), "", false);
814
CachedDirectory directory(tmp_path, set_of_table_definition_ext);
816
if (not schema_name.compare("information_schema"))
818
else if (not schema_name.compare("data_dictionary"))
822
if (directory.fail())
824
errno= directory.getError();
826
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_name.c_str());
828
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
833
for_each(vector_of_engines.begin(), vector_of_engines.end(),
834
AddTableName(directory, schema_name, set_of_names));
836
Session *session= current_session;
838
session->doGetTableNames(directory, schema_name, set_of_names);
640
842
/* This will later be converted to TableIdentifiers */
641
843
class DropTables: public unary_function<StorageEngine *, void>
643
845
Session &session;
644
TableIdentifierList &table_identifiers;
846
TableNameList &set_of_names;
648
DropTables(Session &session_arg, TableIdentifierList &table_identifiers_arg) :
850
DropTables(Session &session_arg, set<string>& of_names) :
649
851
session(session_arg),
650
table_identifiers(table_identifiers_arg)
852
set_of_names(of_names)
653
855
result_type operator() (argument_type engine)
655
for (TableIdentifierList::iterator iter= table_identifiers.begin();
656
iter != table_identifiers.end();
857
for (TableNameList::iterator iter= set_of_names.begin();
858
iter != set_of_names.end();
659
int error= engine->doDropTable(session, const_cast<TableIdentifier&>(*iter));
861
TableIdentifier dummy((*iter).c_str());
862
int error= engine->doDropTable(session, dummy);
661
864
// On a return of zero we know we found and deleted the table. So we
662
865
// remove it from our search.
664
table_identifiers.erase(iter);
867
set_of_names.erase(iter);
1016
1214
int StorageEngine::renameDefinitionFromPath(TableIdentifier &dest, TableIdentifier &src)
1018
message::Table table_message;
1019
1216
string src_path(src.getPath());
1020
1217
string dest_path(dest.getPath());
1022
1219
src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1023
1220
dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1025
bool was_read= StorageEngine::readTableFile(src_path.c_str(), table_message);
1032
dest.copyToTableMessage(table_message);
1034
int error= StorageEngine::writeDefinitionFromPath(dest, table_message);
1038
if (unlink(src_path.c_str()))
1039
perror(src_path.c_str());
1222
return internal::my_rename(src_path.c_str(), dest_path.c_str(), MYF(MY_WME));
1045
1225
int StorageEngine::writeDefinitionFromPath(TableIdentifier &identifier, message::Table &table_message)
1047
char definition_file_tmp[FN_REFLEN];
1048
1227
string file_name(identifier.getPath());
1050
1229
file_name.append(DEFAULT_DEFINITION_FILE_EXT);
1052
snprintf(definition_file_tmp, sizeof(definition_file_tmp), "%sXXXXXX", file_name.c_str());
1054
int fd= mkstemp(definition_file_tmp);
1231
int fd= open(file_name.c_str(), O_RDWR|O_CREAT|O_TRUNC, internal::my_umask);
1058
perror(definition_file_tmp);
1062
1236
google::protobuf::io::ZeroCopyOutputStream* output=
1063
1237
new google::protobuf::io::FileOutputStream(fd);
1065
if (not table_message.SerializeToZeroCopyStream(output))
1239
if (table_message.SerializeToZeroCopyStream(output) == false)
1067
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1068
table_message.InitializationErrorString().c_str());
1071
if (close(fd) == -1)
1072
perror(definition_file_tmp);
1074
if (unlink(definition_file_tmp) == -1)
1075
perror(definition_file_tmp);
1077
return ER_CORRUPT_TABLE_DEFINITION;
1082
if (close(fd) == -1)
1085
perror(definition_file_tmp);
1087
if (unlink(definition_file_tmp))
1088
perror(definition_file_tmp);
1093
if (rename(definition_file_tmp, file_name.c_str()) == -1)
1096
perror(definition_file_tmp);
1098
if (unlink(definition_file_tmp))
1099
perror(definition_file_tmp);
1107
1251
class CanCreateTable: public unary_function<StorageEngine *, bool>
1109
TableIdentifier &identifier;
1253
const TableIdentifier &identifier;
1112
CanCreateTable(TableIdentifier &identifier_arg) :
1256
CanCreateTable(const TableIdentifier &identifier_arg) :
1113
1257
identifier(identifier_arg)