187
168
vector_of_engines.clear();
188
169
vector_of_schema_engines.clear();
170
vector_of_data_dictionary.clear();
190
172
shutdown_has_begun= true;
194
176
class FindEngineByName
195
: public std::unary_function<StorageEngine *, bool>
177
: public unary_function<StorageEngine *, bool>
197
const std::string &predicate;
179
const string ⌖
200
explicit FindEngineByName(const std::string &target_arg) :
201
predicate(target_arg)
182
explicit FindEngineByName(const string &target_arg) :
205
186
result_type operator() (argument_type engine)
207
return boost::iequals(engine->getName(), predicate);
188
string engine_name(engine->getName());
190
transform(engine_name.begin(), engine_name.end(),
191
engine_name.begin(), ::tolower);
192
return engine_name == target;
211
StorageEngine *StorageEngine::findByName(const std::string &predicate)
196
StorageEngine *StorageEngine::findByName(const string &find_str)
213
EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
214
vector_of_engines.end(),
215
FindEngineByName(predicate));
198
string search_string(find_str);
199
transform(search_string.begin(), search_string.end(),
200
search_string.begin(), ::tolower);
203
EngineVector::iterator iter= find_if(vector_of_engines.begin(),
204
vector_of_engines.end(),
205
FindEngineByName(search_string));
216
206
if (iter != vector_of_engines.end())
218
208
StorageEngine *engine= *iter;
367
361
or any dropped tables that need to be removed from disk
369
363
int StorageEngine::getTableDefinition(Session& session,
370
const identifier::Table &identifier,
371
message::table::shared_ptr &table_message,
364
TableIdentifier &identifier,
365
message::Table &table_message,
372
366
bool include_temporary_tables)
374
drizzled::error_t err= static_cast<drizzled::error_t>(ENOENT);
376
370
if (include_temporary_tables)
378
Table *table= session.find_temporary_table(identifier);
381
table_message.reset(new message::Table(*table->getShare()->getTableMessage()));
372
if (session.doGetTableDefinition(identifier, table_message) == EEXIST)
386
drizzled::message::table::shared_ptr table_ptr;
387
if ((table_ptr= drizzled::message::Cache::singleton().find(identifier)))
389
table_message= table_ptr;
392
message::Table message;
393
376
EngineVector::iterator iter=
394
std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
395
StorageEngineGetTableDefinition(session, identifier, message, err));
377
find_if(vector_of_engines.begin(), vector_of_engines.end(),
378
StorageEngineGetTableDefinition(session, identifier, table_message, err));
397
380
if (iter == vector_of_engines.end())
401
table_message.reset(new message::Table(message));
403
drizzled::message::Cache::singleton().insert(identifier, table_message);
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)
413
error= static_cast<drizzled::error_t>(ENOENT);
415
if (include_temporary_tables)
417
Table *table= session.find_temporary_table(identifier);
421
return message::table::shared_ptr(new message::Table(*table->getShare()->getTableMessage()));
425
drizzled::message::table::shared_ptr table_ptr;
426
if ((table_ptr= drizzled::message::Cache::singleton().find(identifier)))
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));
436
if (iter == vector_of_engines.end())
438
error= static_cast<drizzled::error_t>(ENOENT);
439
return message::table::shared_ptr();
441
message::table::shared_ptr table_message(new message::Table(message));
443
drizzled::message::Cache::singleton().insert(identifier, table_message);
445
return table_message;
449
389
An interceptor to hijack the text of the error message without
450
390
setting an error in the thread. We need the text to present it
478
class DropTableByIdentifier: public std::unary_function<EngineVector::value_type, bool>
419
public unary_function<StorageEngine *, void>
480
Session::reference session;
481
identifier::Table::const_reference identifier;
482
drizzled::error_t &error;
421
uint64_t &success_count;
422
TableIdentifier &identifier;
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),
427
DropTable(Session &session_arg, TableIdentifier &arg, uint64_t &count_arg) :
428
success_count(count_arg),
494
434
result_type operator() (argument_type engine)
496
if (not engine->doDoesTableExist(session, identifier))
499
int local_error= engine->doDropTable(session, identifier);
507
case HA_ERR_NO_SUCH_TABLE:
509
error= static_cast<drizzled::error_t>(HA_ERR_NO_SUCH_TABLE);
513
error= static_cast<drizzled::error_t>(local_error);
436
bool success= engine->doDropTable(session, identifier);
520
bool StorageEngine::dropTable(Session::reference session,
521
identifier::Table::const_reference identifier,
522
drizzled::error_t &error)
526
EngineVector::const_iterator iter= std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
527
DropTableByIdentifier(session, identifier, error));
533
else if (iter == vector_of_engines.end())
535
error= ER_BAD_TABLE_ERROR;
539
drizzled::message::Cache::singleton().erase(identifier);
544
bool StorageEngine::dropTable(Session& session,
545
const identifier::Table &identifier)
547
drizzled::error_t error;
549
if (not dropTable(session, identifier, error))
557
bool StorageEngine::dropTable(Session::reference session,
558
StorageEngine &engine,
559
identifier::Table::const_reference identifier,
560
drizzled::error_t &error)
445
returns ENOENT if the file doesn't exists.
447
int StorageEngine::dropTable(Session& session,
448
TableIdentifier &identifier)
452
message::Table src_proto;
453
StorageEngine *engine;
455
error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
457
if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
459
string error_message;
461
error_message.append(identifier.getSQLPath());
462
error_message.append(" : ");
463
error_message.append(src_proto.InitializationErrorString());
465
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
467
return ER_CORRUPT_TABLE_DEFINITION;
470
engine= StorageEngine::findByName(session, src_proto.engine().name());
474
error= StorageEngine::dropTable(session, *engine, identifier);
477
if (error_proto && error == 0)
483
int StorageEngine::dropTable(Session& session,
484
StorageEngine &engine,
485
TableIdentifier &identifier)
563
489
engine.setTransactionReadWrite(session);
565
assert(identifier.isTmp());
567
if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
569
error= ER_EVENT_OBSERVER_PLUGIN;
573
error= static_cast<drizzled::error_t>(engine.doDropTable(session, identifier));
575
if (unlikely(plugin::EventObserver::afterDropTable(session, identifier, error)))
490
error= engine.doDropTable(session, identifier);
494
if (not engine.check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
577
error= ER_EVENT_OBSERVER_PLUGIN;
496
uint64_t counter; // @todo We need to refactor to check that.
498
for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
499
DropTable(session, identifier, counter));
581
drizzled::message::Cache::singleton().erase(identifier);
593
507
Initiates table-file and calls appropriate database-creator.
600
bool StorageEngine::createTable(Session &session,
601
const identifier::Table &identifier,
602
message::Table& table_message)
514
int StorageEngine::createTable(Session &session,
515
TableIdentifier &identifier,
516
bool update_create_info,
517
message::Table& table_message)
604
drizzled::error_t error= EE_OK;
606
TableShare share(identifier);
607
table::Shell table(share);
521
TableShare share(identifier.getDBName().c_str(), 0, identifier.getTableName().c_str(), identifier.getPath().c_str());
608
522
message::Table tmp_proto;
610
if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
524
if (parse_table_proto(session, table_message, &share) || open_table_from_share(&session, &share, "", 0, 0, &table))
612
526
// @note Error occured, we should probably do a little more here.
613
// ER_CORRUPT_TABLE_DEFINITION,ER_CORRUPT_TABLE_DEFINITION_ENUM
615
my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN, identifier);
530
if (update_create_info)
531
table.updateCreateInfo(&table_message);
621
533
/* Check for legal operations against the Engine using the proto (if used) */
622
534
if (table_message.type() == message::Table::TEMPORARY &&
623
535
share.storage_engine->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED) == true)
634
share.storage_engine->setTransactionReadWrite(session);
636
error= static_cast<drizzled::error_t>(share.storage_engine->doCreateTable(session,
642
if (error == ER_TABLE_PERMISSION_DENIED)
644
my_error(ER_TABLE_PERMISSION_DENIED, identifier);
649
identifier.getSQLPath(path);
650
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), path.c_str(), error);
653
table.delete_table();
546
bool do_create= true;
547
if (not share.storage_engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
549
int protoerr= StorageEngine::writeDefinitionFromPath(identifier, table_message);
560
share.storage_engine->setTransactionReadWrite(session);
562
error= share.storage_engine->doCreateTable(&session,
571
if (not share.storage_engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
572
plugin::StorageEngine::deleteDefinitionFromPath(identifier);
574
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), identifier.getSQLPath().c_str(), error);
577
table.closefrm(false);
656
return(error == EE_OK);
659
Cursor *StorageEngine::getCursor(Table &arg)
664
class AddTableIdentifier :
665
public std::unary_function<StorageEngine *, void>
667
CachedDirectory &directory;
668
const identifier::Schema &identifier;
669
identifier::Table::vector &set_of_identifiers;
580
share.free_table_share();
584
Cursor *StorageEngine::getCursor(TableShare &share, memory::Root *alloc)
586
return create(share, alloc);
590
TODO -> Remove this to force all engines to implement their own file. Solves the "we only looked at dfe" problem.
592
void StorageEngine::doGetTableNames(CachedDirectory&, string&, set<string>&)
596
public unary_function<StorageEngine *, void>
599
CachedDirectory& directory;
600
TableNameList &set_of_names;
673
AddTableIdentifier(CachedDirectory &directory_arg, const identifier::Schema &identifier_arg, identifier::Table::vector &of_names) :
604
AddTableName(CachedDirectory& directory_arg, const string& database_name, set<string>& of_names) :
674
605
directory(directory_arg),
675
identifier(identifier_arg),
676
set_of_identifiers(of_names)
680
result_type operator() (argument_type engine)
682
engine->doGetTableIdentifiers(directory, identifier, set_of_identifiers);
687
void StorageEngine::getIdentifiers(Session &session, const identifier::Schema &schema_identifier, identifier::Table::vector &set_of_identifiers)
689
CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
691
if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
606
set_of_names(of_names)
611
result_type operator() (argument_type engine)
613
engine->doGetTableNames(directory, db, set_of_names);
617
class AddSchemaNames :
618
public unary_function<StorageEngine *, void>
620
SchemaNameList &set_of_names;
624
AddSchemaNames(set<string>& of_names) :
625
set_of_names(of_names)
629
result_type operator() (argument_type engine)
631
engine->doGetSchemaNames(set_of_names);
635
void StorageEngine::getSchemaNames(SchemaNameList &set_of_names)
637
// Add hook here for engines to register schema.
638
for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
639
AddSchemaNames(set_of_names));
641
plugin::Authorization::pruneSchemaNames(current_session->getSecurityContext(),
645
class StorageEngineGetSchemaDefinition: public unary_function<StorageEngine *, bool>
647
std::string schema_name;
648
message::Schema &schema_proto;
651
StorageEngineGetSchemaDefinition(const std::string schema_name_arg,
652
message::Schema &schema_proto_arg) :
653
schema_name(schema_name_arg),
654
schema_proto(schema_proto_arg)
656
transform(schema_name.begin(), schema_name.end(),
657
schema_name.begin(), ::tolower);
660
result_type operator() (argument_type engine)
662
return engine->doGetSchemaDefinition(schema_name, schema_proto);
667
Return value is "if parsed"
669
bool StorageEngine::getSchemaDefinition(TableIdentifier &identifier, message::Schema &proto)
671
return StorageEngine::getSchemaDefinition(identifier.getSchemaName(), proto);
674
bool StorageEngine::getSchemaDefinition(const std::string &schema_name, message::Schema &proto)
678
EngineVector::iterator iter=
679
find_if(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
680
StorageEngineGetSchemaDefinition(schema_name, proto));
682
if (iter != vector_of_schema_engines.end())
690
bool StorageEngine::doesSchemaExist(const std::string &schema_name)
692
message::Schema proto;
694
return StorageEngine::getSchemaDefinition(schema_name, proto);
697
bool StorageEngine::doesSchemaExist(TableIdentifier &identifier)
699
message::Schema proto;
701
return StorageEngine::getSchemaDefinition(identifier.getSchemaName(), proto);
705
const CHARSET_INFO *StorageEngine::getSchemaCollation(const std::string &schema_name)
707
message::Schema schmema_proto;
710
found= StorageEngine::getSchemaDefinition(schema_name, schmema_proto);
712
if (found && schmema_proto.has_collation())
714
const string buffer= schmema_proto.collation();
715
const CHARSET_INFO* cs= get_charset_by_name(buffer.c_str());
719
errmsg_printf(ERRMSG_LVL_ERROR,
720
_("Error while loading database options: '%s':"), schema_name.c_str());
721
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
723
return default_charset_info;
729
return default_charset_info;
733
public unary_function<StorageEngine *, void>
735
const drizzled::message::Schema &schema_message;
739
CreateSchema(const drizzled::message::Schema &arg) :
744
result_type operator() (argument_type engine)
746
// @todo eomeday check that at least one engine said "true"
747
(void)engine->doCreateSchema(schema_message);
751
bool StorageEngine::createSchema(const drizzled::message::Schema &schema_message)
753
// Add hook here for engines to register schema.
754
for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
755
CreateSchema(schema_message));
761
public unary_function<StorageEngine *, void>
763
uint64_t &success_count;
764
const string &schema_name;
768
DropSchema(const string &arg, uint64_t &count_arg) :
769
success_count(count_arg),
774
result_type operator() (argument_type engine)
776
// @todo someday check that at least one engine said "true"
777
bool success= engine->doDropSchema(schema_name);
784
bool StorageEngine::dropSchema(const string &schema_name)
787
// Add hook here for engines to register schema.
788
for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
789
DropSchema(schema_name, counter));
791
return counter ? true : false;
795
public unary_function<StorageEngine *, void>
797
uint64_t &success_count;
798
const drizzled::message::Schema &schema_message;
802
AlterSchema(const drizzled::message::Schema &arg, uint64_t &count_arg) :
803
success_count(count_arg),
808
result_type operator() (argument_type engine)
810
// @todo eomeday check that at least one engine said "true"
811
bool success= engine->doAlterSchema(schema_message);
818
bool StorageEngine::alterSchema(const drizzled::message::Schema &schema_message)
820
uint64_t success_count= 0;
822
for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
823
AlterSchema(schema_message, success_count));
825
return success_count ? true : false;
829
void StorageEngine::getTableNames(const string &schema_name, TableNameList &set_of_names)
833
build_table_filename(tmp_path, schema_name.c_str(), "", false);
835
CachedDirectory directory(tmp_path, set_of_table_definition_ext);
837
if (not schema_name.compare("information_schema"))
693
else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
839
else if (not schema_name.compare("data_dictionary"))
699
845
errno= directory.getError();
700
846
if (errno == ENOENT)
703
schema_identifier.getSQLPath(path);
704
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), path.c_str());
847
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_name.c_str());
708
849
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
715
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
716
AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
718
session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
854
for_each(vector_of_engines.begin(), vector_of_engines.end(),
855
AddTableName(directory, schema_name, set_of_names));
857
Session *session= current_session;
859
session->doGetTableNames(directory, schema_name, set_of_names);
721
class DropTable: public std::unary_function<identifier::Table&, bool>
724
StorageEngine *engine;
728
DropTable(Session &session_arg, StorageEngine *engine_arg) :
729
session(session_arg),
733
result_type operator() (argument_type identifier)
735
return engine->doDropTable(session, identifier) == 0;
739
/* This will later be converted to identifier::Tables */
740
class DropTables: public std::unary_function<StorageEngine *, void>
743
identifier::Table::vector &table_identifiers;
747
DropTables(Session &session_arg, identifier::Table::vector &table_identifiers_arg) :
863
/* This will later be converted to TableIdentifiers */
864
class DropTables: public unary_function<StorageEngine *, void>
867
TableIdentifierList &table_identifiers;
871
DropTables(Session &session_arg, TableIdentifierList &table_identifiers_arg) :
748
872
session(session_arg),
749
873
table_identifiers(table_identifiers_arg)
752
876
result_type operator() (argument_type engine)
754
// True returning from DropTable means the table has been successfully
755
// 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)),
759
table_identifiers.end());
878
for (TableIdentifierList::iterator iter= table_identifiers.begin();
879
iter != table_identifiers.end();
882
int error= engine->doDropTable(session, const_cast<TableIdentifier&>(*iter));
884
// On a return of zero we know we found and deleted the table. So we
885
// remove it from our search.
887
table_identifiers.erase(iter);