82
78
return vector_of_schema_engines;
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 */
194
190
class FindEngineByName
195
: public std::unary_function<StorageEngine *, bool>
191
: public unary_function<StorageEngine *, bool>
197
const std::string &predicate;
193
const string ⌖
200
explicit FindEngineByName(const std::string &target_arg) :
201
predicate(target_arg)
196
explicit FindEngineByName(const string &target_arg) :
205
200
result_type operator() (argument_type engine)
207
return boost::iequals(engine->getName(), predicate);
202
string engine_name(engine->getName());
204
transform(engine_name.begin(), engine_name.end(),
205
engine_name.begin(), ::tolower);
206
return engine_name == target;
211
StorageEngine *StorageEngine::findByName(const std::string &predicate)
210
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));
212
string search_string(find_str);
213
transform(search_string.begin(), search_string.end(),
214
search_string.begin(), ::tolower);
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())
218
222
StorageEngine *engine= *iter;
226
StorageEngine *StorageEngine::findByName(Session& session, const std::string &predicate)
230
StorageEngine *StorageEngine::findByName(Session& session, const string &find_str)
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);
236
if (search_string.compare("default") == 0)
229
237
return session.getDefaultStorageEngine();
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())
236
244
StorageEngine *engine= *iter;
264
272
void StorageEngine::closeConnection(Session* session)
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));
270
278
bool StorageEngine::flushLogs(StorageEngine *engine)
272
280
if (engine == NULL)
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())
287
class StorageEngineGetTableDefinition: public std::unary_function<StorageEngine *,bool>
295
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
289
297
Session& session;
290
const identifier::Table &identifier;
298
const TableIdentifier &identifier;
291
299
message::Table &table_message;
292
drizzled::error_t &err;
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) :
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);
308
316
if (ret != ENOENT)
309
err= static_cast<drizzled::error_t>(ret);
311
return err == static_cast<drizzled::error_t>(EEXIST) or err != static_cast<drizzled::error_t>(ENOENT);
319
return err == EEXIST || err != ENOENT;
315
class StorageEngineDoesTableExist: public std::unary_function<StorageEngine *, bool>
323
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
317
325
Session& session;
318
const identifier::Table &identifier;
326
const TableIdentifier &identifier;
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)
367
375
or any dropped tables that need to be removed from disk
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)
374
drizzled::error_t err= static_cast<drizzled::error_t>(ENOENT);
376
384
if (include_temporary_tables)
378
Table *table= session.find_temporary_table(identifier);
381
table_message.reset(new message::Table(*table->getShare()->getTableMessage()));
386
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
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));
397
394
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
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
478
class DropTableByIdentifier: public std::unary_function<EngineVector::value_type, bool>
480
Session::reference session;
481
identifier::Table::const_reference identifier;
482
drizzled::error_t &error;
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),
494
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);
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)
433
returns ENOENT if the file doesn't exists.
435
int StorageEngine::dropTable(Session& session,
436
const TableIdentifier &identifier)
440
message::Table src_proto;
441
StorageEngine *engine;
443
error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
445
if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
447
string error_message;
449
error_message.append(const_cast<TableIdentifier &>(identifier).getSQLPath());
450
error_message.append(" : ");
451
error_message.append(src_proto.InitializationErrorString());
453
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
455
return ER_CORRUPT_TABLE_DEFINITION;
458
engine= StorageEngine::findByName(session, src_proto.engine().name());
462
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str());
464
return ER_CORRUPT_TABLE_DEFINITION;
467
error= StorageEngine::dropTable(session, *engine, identifier);
469
if (error_proto && error == 0)
475
int StorageEngine::dropTable(Session& session,
476
StorageEngine &engine,
477
const TableIdentifier &identifier)
563
481
engine.setTransactionReadWrite(session);
565
assert(identifier.isTmp());
567
483
if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
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)
604
drizzled::error_t error= EE_OK;
606
515
TableShare share(identifier);
607
table::Shell table(share);
608
516
message::Table tmp_proto;
610
518
if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
612
520
// @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);
634
537
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();
656
return(error == EE_OK);
659
Cursor *StorageEngine::getCursor(Table &arg)
539
error= share.storage_engine->doCreateTable(session,
547
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
550
table.delete_table(false);
556
Cursor *StorageEngine::getCursor(TableShare &share, memory::Root *alloc)
558
return create(share, alloc);
562
public unary_function<StorageEngine *, void>
564
CachedDirectory &directory;
565
SchemaIdentifier &identifier;
566
TableNameList &set_of_names;
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)
577
result_type operator() (argument_type engine)
579
engine->doGetTableNames(directory, identifier, set_of_names);
664
583
class AddTableIdentifier :
665
public std::unary_function<StorageEngine *, void>
584
public unary_function<StorageEngine *, void>
667
586
CachedDirectory &directory;
668
const identifier::Schema &identifier;
669
identifier::Table::vector &set_of_identifiers;
587
SchemaIdentifier &identifier;
588
TableIdentifiers &set_of_identifiers;
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)
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)
693
else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
697
if (directory.fail())
699
errno= directory.getError();
703
schema_identifier.getSQLPath(path);
704
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), path.c_str());
708
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));
606
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
607
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
609
void StorageEngine::getTableNames(Session &session, SchemaIdentifier &schema_identifier, TableNameList &set_of_names)
611
CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
613
if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
615
else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
619
if (directory.fail())
621
errno= directory.getError();
623
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
625
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
630
for_each(vector_of_engines.begin(), vector_of_engines.end(),
631
AddTableName(directory, schema_identifier, set_of_names));
633
session.doGetTableNames(directory, schema_identifier, set_of_names);
636
void StorageEngine::getTableIdentifiers(Session &session, SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
638
CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
640
if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
642
else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
646
if (directory.fail())
648
errno= directory.getError();
650
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
652
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
657
for_each(vector_of_engines.begin(), vector_of_engines.end(),
658
AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
718
660
session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
721
class DropTable: public std::unary_function<identifier::Table&, bool>
663
class DropTable: public unary_function<TableIdentifier&, bool>
723
665
Session &session;
724
666
StorageEngine *engine;
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>
742
684
Session &session;
743
identifier::Table::vector &table_identifiers;
685
TableIdentifierList &table_identifiers;
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)
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());
797
739
message::Table definition;
798
740
if (StorageEngine::readTableFile(path, definition))
800
identifier::Table identifier(definition.schema(), definition.name(), path);
742
TableIdentifier identifier(definition.schema(), definition.name(), path);
801
743
table_identifiers.push_back(identifier);
805
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
806
DropTables(session, table_identifiers));
747
for_each(vector_of_engines.begin(), vector_of_engines.end(),
748
DropTables(session, table_identifiers));
809
751
Now we just clean up anything that might left over.
811
753
We rescan because some of what might have been there should
812
754
now be all nice and cleaned up.
814
std::set<std::string> all_exts= set_of_table_definition_ext;
756
set<string> all_exts= set_of_table_definition_ext;
816
758
for (EngineVector::iterator iter= vector_of_engines.begin();
817
759
iter != vector_of_engines.end() ; iter++)
847
789
- table->getShare()->path
850
void StorageEngine::print_error(int error, myf errflag, const Table &table) const
852
drizzled::error_t textno= ER_GET_ERRNO;
792
void StorageEngine::print_error(int error, myf errflag, Table &table)
794
print_error(error, errflag, &table);
797
void StorageEngine::print_error(int error, myf errflag, Table *table)
799
int textno= ER_GET_ERRNO;
855
802
textno=ER_OPEN_AS_READONLY;
894
843
String str(key,sizeof(key),system_charset_info);
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)
979
928
textno=ER_TABLE_DEF_CHANGED;
981
930
case HA_ERR_NO_SUCH_TABLE:
983
identifier::Table identifier(table.getShare()->getSchemaName(), table.getShare()->getTableName());
984
my_error(ER_TABLE_UNKNOWN, identifier);
932
my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
933
table->getShare()->getTableName());
987
935
case HA_ERR_RBR_LOGGING_FAILED:
988
936
textno= ER_BINLOG_ROW_LOGGING_FAILED;
990
938
case HA_ERR_DROP_INDEX_FK:
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);
1052
1000
Returns true if this is a temporary error
1054
bool StorageEngine::get_error_message(int , String* ) const
1002
bool StorageEngine::get_error_message(int , String* )
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)
1062
1010
/* Write the duplicated key in the error message */
1063
1011
char key[MAX_KEY_LENGTH];
1088
int StorageEngine::deleteDefinitionFromPath(const identifier::Table &identifier)
1036
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1090
std::string path(identifier.getPath());
1038
string path(identifier.getPath());
1092
1040
path.append(DEFAULT_DEFINITION_FILE_EXT);
1094
1042
return internal::my_delete(path.c_str(), MYF(0));
1097
int StorageEngine::renameDefinitionFromPath(const identifier::Table &dest, const identifier::Table &src)
1045
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
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());
1103
1051
src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1104
1052
dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1220
1163
@note on success table can be created.
1222
bool StorageEngine::canCreateTable(const identifier::Table &identifier)
1165
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
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));
1228
1171
if (iter == vector_of_engines.end())