82
77
return vector_of_schema_engines;
85
StorageEngine::StorageEngine(const std::string name_arg,
86
const std::bitset<HTON_BIT_SIZE> &flags_arg) :
80
StorageEngine::StorageEngine(const string name_arg,
81
const bitset<HTON_BIT_SIZE> &flags_arg) :
87
82
Plugin(name_arg, "StorageEngine"),
88
83
MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
104
int StorageEngine::renameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
99
int StorageEngine::renameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
107
101
setTransactionReadWrite(session);
109
if (unlikely(plugin::EventObserver::beforeRenameTable(session, from, to)))
111
error= ER_EVENT_OBSERVER_PLUGIN;
115
error = doRenameTable(session, from, to);
116
if (unlikely(plugin::EventObserver::afterRenameTable(session, from, to, error)))
118
error= ER_EVENT_OBSERVER_PLUGIN;
103
return doRenameTable(session, from, to);
194
175
class FindEngineByName
195
: public std::unary_function<StorageEngine *, bool>
176
: public unary_function<StorageEngine *, bool>
197
const std::string &predicate;
178
const string ⌖
200
explicit FindEngineByName(const std::string &target_arg) :
201
predicate(target_arg)
181
explicit FindEngineByName(const string &target_arg) :
205
185
result_type operator() (argument_type engine)
207
return boost::iequals(engine->getName(), predicate);
187
string engine_name(engine->getName());
189
transform(engine_name.begin(), engine_name.end(),
190
engine_name.begin(), ::tolower);
191
return engine_name == target;
211
StorageEngine *StorageEngine::findByName(const std::string &predicate)
195
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));
197
string search_string(find_str);
198
transform(search_string.begin(), search_string.end(),
199
search_string.begin(), ::tolower);
202
EngineVector::iterator iter= find_if(vector_of_engines.begin(),
203
vector_of_engines.end(),
204
FindEngineByName(search_string));
216
205
if (iter != vector_of_engines.end())
218
207
StorageEngine *engine= *iter;
226
StorageEngine *StorageEngine::findByName(Session& session, const std::string &predicate)
215
StorageEngine *StorageEngine::findByName(Session& session, const string &find_str)
228
if (boost::iequals(predicate, DEFAULT_STRING))
217
string search_string(find_str);
218
transform(search_string.begin(), search_string.end(),
219
search_string.begin(), ::tolower);
221
if (search_string.compare("default") == 0)
229
222
return session.getDefaultStorageEngine();
231
EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
232
vector_of_engines.end(),
233
FindEngineByName(predicate));
224
EngineVector::iterator iter= find_if(vector_of_engines.begin(),
225
vector_of_engines.end(),
226
FindEngineByName(search_string));
234
227
if (iter != vector_of_engines.end())
236
229
StorageEngine *engine= *iter;
264
257
void StorageEngine::closeConnection(Session* session)
266
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
267
StorageEngineCloseConnection(session));
259
for_each(vector_of_engines.begin(), vector_of_engines.end(),
260
StorageEngineCloseConnection(session));
270
263
bool StorageEngine::flushLogs(StorageEngine *engine)
272
265
if (engine == NULL)
274
if (std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
std::mem_fun(&StorageEngine::flush_logs))
267
if (find_if(vector_of_engines.begin(), vector_of_engines.end(),
268
mem_fun(&StorageEngine::flush_logs))
276
269
!= vector_of_engines.begin())
287
class StorageEngineGetTableDefinition: public std::unary_function<StorageEngine *,bool>
280
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
289
282
Session& session;
290
const TableIdentifier &identifier;
283
TableIdentifier &identifier;
291
284
message::Table &table_message;
295
288
StorageEngineGetTableDefinition(Session& session_arg,
296
const TableIdentifier &identifier_arg,
289
TableIdentifier &identifier_arg,
297
290
message::Table &table_message_arg,
299
292
session(session_arg),
315
class StorageEngineDoesTableExist: public std::unary_function<StorageEngine *, bool>
308
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
317
310
Session& session;
318
const TableIdentifier &identifier;
311
TableIdentifier &identifier;
321
StorageEngineDoesTableExist(Session& session_arg, const TableIdentifier &identifier_arg) :
314
StorageEngineDoesTableExist(Session& session_arg, TableIdentifier &identifier_arg) :
322
315
session(session_arg),
323
316
identifier(identifier_arg)
333
326
Utility method which hides some of the details of getTableDefinition()
335
328
bool plugin::StorageEngine::doesTableExist(Session &session,
336
const TableIdentifier &identifier,
329
TableIdentifier &identifier,
337
330
bool include_temporary_tables)
339
332
if (include_temporary_tables)
345
338
EngineVector::iterator iter=
346
std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
347
StorageEngineDoesTableExist(session, identifier));
339
find_if(vector_of_engines.begin(), vector_of_engines.end(),
340
StorageEngineDoesTableExist(session, identifier));
349
342
if (iter == vector_of_engines.end())
367
360
or any dropped tables that need to be removed from disk
369
362
int StorageEngine::getTableDefinition(Session& session,
370
const TableIdentifier &identifier,
371
message::table::shared_ptr &table_message,
363
TableIdentifier &identifier,
364
message::Table &table_message,
372
365
bool include_temporary_tables)
376
369
if (include_temporary_tables)
378
Table *table= session.find_temporary_table(identifier);
381
table_message.reset(new message::Table(*table->getShare()->getTableProto()));
371
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
375
EngineVector::iterator iter=
394
std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
395
StorageEngineGetTableDefinition(session, identifier, message, err));
376
find_if(vector_of_engines.begin(), vector_of_engines.end(),
377
StorageEngineGetTableDefinition(session, identifier, table_message, err));
397
379
if (iter == vector_of_engines.end())
401
table_message.reset(new message::Table(message));
403
drizzled::message::Cache::singleton().insert(identifier, table_message);
439
418
returns ENOENT if the file doesn't exists.
441
420
int StorageEngine::dropTable(Session& session,
442
const TableIdentifier &identifier)
421
TableIdentifier &identifier)
446
message::table::shared_ptr src_proto;
425
message::Table src_proto;
447
426
StorageEngine *engine;
449
428
error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
451
430
if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
453
std::string error_message;
454
identifier.getSQLPath(error_message);
432
string error_message;
434
error_message.append(identifier.getSQLPath());
456
435
error_message.append(" : ");
457
error_message.append(src_proto->InitializationErrorString());
436
error_message.append(src_proto.InitializationErrorString());
459
438
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
461
440
return ER_CORRUPT_TABLE_DEFINITION;
465
engine= StorageEngine::findByName(session, src_proto->engine().name());
467
engine= StorageEngine::findByName(session, "");
443
engine= StorageEngine::findByName(session, src_proto.engine().name());
471
std::string error_message;
472
identifier.getSQLPath(error_message);
473
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
447
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), identifier.getSQLPath().c_str());
475
449
return ER_CORRUPT_TABLE_DEFINITION;
486
460
int StorageEngine::dropTable(Session& session,
487
461
StorageEngine &engine,
488
const TableIdentifier &identifier)
462
TableIdentifier &identifier)
492
466
engine.setTransactionReadWrite(session);
494
if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
496
error= ER_EVENT_OBSERVER_PLUGIN;
500
error= engine.doDropTable(session, identifier);
501
if (unlikely(plugin::EventObserver::afterDropTable(session, identifier, error)))
503
error= ER_EVENT_OBSERVER_PLUGIN;
507
drizzled::message::Cache::singleton().erase(identifier);
467
error= engine.doDropTable(session, identifier);
521
481
int StorageEngine::createTable(Session &session,
522
const TableIdentifier &identifier,
482
TableIdentifier &identifier,
483
bool update_create_info,
523
484
message::Table& table_message)
526
TableShare share(identifier);
527
table::Shell table(share);
488
TableShare share(identifier.getSchemaName().c_str(), 0, identifier.getTableName().c_str(), identifier.getPath().c_str());
528
489
message::Table tmp_proto;
530
if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
491
if (parse_table_proto(session, table_message, &share) || open_table_from_share(&session, &share, "", 0, 0, &table))
532
493
// @note Error occured, we should probably do a little more here.
497
if (update_create_info)
498
table.updateCreateInfo(&table_message);
536
500
/* Check for legal operations against the Engine using the proto (if used) */
537
501
if (table_message.type() == message::Table::TEMPORARY &&
538
502
share.storage_engine->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED) == true)
560
identifier.getSQLPath(path);
561
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), path.c_str(), error);
523
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), identifier.getSQLPath().c_str(), error);
564
table.delete_table();
526
table.closefrm(false);
529
share.free_table_share();
567
530
return(error != 0);
570
Cursor *StorageEngine::getCursor(Table &arg)
533
Cursor *StorageEngine::getCursor(TableShare &share, memory::Root *alloc)
535
return create(share, alloc);
575
class AddTableIdentifier :
576
public std::unary_function<StorageEngine *, void>
539
TODO -> Remove this to force all engines to implement their own file. Solves the "we only looked at dfe" problem.
541
void StorageEngine::doGetTableNames(CachedDirectory&, SchemaIdentifier&, set<string>&)
545
public unary_function<StorageEngine *, void>
578
547
CachedDirectory &directory;
579
const SchemaIdentifier &identifier;
580
TableIdentifier::vector &set_of_identifiers;
548
SchemaIdentifier &identifier;
549
TableNameList &set_of_names;
584
AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifier::vector &of_names) :
553
AddTableName(CachedDirectory &directory_arg, SchemaIdentifier &identifier_arg, set<string>& of_names) :
585
554
directory(directory_arg),
586
555
identifier(identifier_arg),
587
set_of_identifiers(of_names)
556
set_of_names(of_names)
591
560
result_type operator() (argument_type engine)
593
engine->doGetTableIdentifiers(directory, identifier, set_of_identifiers);
562
engine->doGetTableNames(directory, identifier, set_of_names);
598
void StorageEngine::getIdentifiers(Session &session, const SchemaIdentifier &schema_identifier, TableIdentifier::vector &set_of_identifiers)
567
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
568
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
570
void StorageEngine::getTableNames(Session &session, SchemaIdentifier &schema_identifier, TableNameList &set_of_names)
600
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
601
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
603
572
CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
605
574
if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
613
582
errno= directory.getError();
614
583
if (errno == ENOENT)
617
schema_identifier.getSQLPath(path);
618
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), path.c_str());
584
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
622
586
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
629
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
630
AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
591
for_each(vector_of_engines.begin(), vector_of_engines.end(),
592
AddTableName(directory, schema_identifier, set_of_names));
632
session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
594
session.doGetTableNames(directory, schema_identifier, set_of_names);
635
class DropTable: public std::unary_function<TableIdentifier&, bool>
638
StorageEngine *engine;
642
DropTable(Session &session_arg, StorageEngine *engine_arg) :
643
session(session_arg),
647
result_type operator() (argument_type identifier)
649
return engine->doDropTable(session, identifier) == 0;
653
597
/* This will later be converted to TableIdentifiers */
654
class DropTables: public std::unary_function<StorageEngine *, void>
598
class DropTables: public unary_function<StorageEngine *, void>
656
600
Session &session;
657
TableIdentifier::vector &table_identifiers;
601
TableIdentifierList &table_identifiers;
661
DropTables(Session &session_arg, TableIdentifier::vector &table_identifiers_arg) :
605
DropTables(Session &session_arg, TableIdentifierList &table_identifiers_arg) :
662
606
session(session_arg),
663
607
table_identifiers(table_identifiers_arg)
666
610
result_type operator() (argument_type engine)
668
// True returning from DropTable means the table has been successfully
669
// 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)),
673
table_identifiers.end());
612
for (TableIdentifierList::iterator iter= table_identifiers.begin();
613
iter != table_identifiers.end();
616
int error= engine->doDropTable(session, const_cast<TableIdentifier&>(*iter));
618
// On a return of zero we know we found and deleted the table. So we
619
// remove it from our search.
621
table_identifiers.erase(iter);
719
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
720
DropTables(session, table_identifiers));
668
for_each(vector_of_engines.begin(), vector_of_engines.end(),
669
DropTables(session, table_identifiers));
723
672
Now we just clean up anything that might left over.
725
674
We rescan because some of what might have been there should
726
675
now be all nice and cleaned up.
728
std::set<std::string> all_exts= set_of_table_definition_ext;
677
set<string> all_exts= set_of_table_definition_ext;
730
679
for (EngineVector::iterator iter= vector_of_engines.begin();
731
680
iter != vector_of_engines.end() ; iter++)
902
858
case HA_ERR_NO_SUCH_TABLE:
904
my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
905
table->getShare()->getTableName());
860
my_error(ER_NO_SUCH_TABLE, MYF(0), table->s->getSchemaName(),
861
table->s->table_name.str);
907
863
case HA_ERR_RBR_LOGGING_FAILED:
908
864
textno= ER_BINLOG_ROW_LOGGING_FAILED;
1008
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
964
int StorageEngine::deleteDefinitionFromPath(TableIdentifier &identifier)
1010
std::string path(identifier.getPath());
966
string path(identifier.getPath());
1012
968
path.append(DEFAULT_DEFINITION_FILE_EXT);
1014
970
return internal::my_delete(path.c_str(), MYF(0));
1017
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
973
int StorageEngine::renameDefinitionFromPath(TableIdentifier &dest, TableIdentifier &src)
1019
975
message::Table table_message;
1020
std::string src_path(src.getPath());
1021
std::string dest_path(dest.getPath());
976
string src_path(src.getPath());
977
string dest_path(dest.getPath());
1023
979
src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1024
980
dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1046
int StorageEngine::writeDefinitionFromPath(const TableIdentifier &identifier, message::Table &table_message)
1002
int StorageEngine::writeDefinitionFromPath(TableIdentifier &identifier, message::Table &table_message)
1048
1004
char definition_file_tmp[FN_REFLEN];
1049
std::string file_name(identifier.getPath());
1005
string file_name(identifier.getPath());
1051
1007
file_name.append(DEFAULT_DEFINITION_FILE_EXT);
1063
1019
google::protobuf::io::ZeroCopyOutputStream* output=
1064
1020
new google::protobuf::io::FileOutputStream(fd);
1070
success= table_message.SerializeToZeroCopyStream(output);
1022
if (not table_message.SerializeToZeroCopyStream(output))
1079
1024
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1080
1025
table_message.InitializationErrorString().c_str());
1119
class CanCreateTable: public std::unary_function<StorageEngine *, bool>
1064
class CanCreateTable: public unary_function<StorageEngine *, bool>
1121
const TableIdentifier &identifier;
1066
TableIdentifier &identifier;
1124
CanCreateTable(const TableIdentifier &identifier_arg) :
1069
CanCreateTable(TableIdentifier &identifier_arg) :
1125
1070
identifier(identifier_arg)
1136
1081
@note on success table can be created.
1138
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1083
bool StorageEngine::canCreateTable(drizzled::TableIdentifier &identifier)
1140
1085
EngineVector::iterator iter=
1141
std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1142
CanCreateTable(identifier));
1086
find_if(vector_of_engines.begin(), vector_of_engines.end(),
1087
CanCreateTable(identifier));
1144
1089
if (iter == vector_of_engines.end())
1152
1097
bool StorageEngine::readTableFile(const std::string &path, message::Table &table_message)
1154
std::fstream input(path.c_str(), std::ios::in | std::ios::binary);
1099
fstream input(path.c_str(), ios::in | ios::binary);
1156
1101
if (input.good())
1159
if (table_message.ParseFromIstream(&input))
1103
if (table_message.ParseFromIstream(&input))
1166
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1167
table_message.InitializationErrorString().empty() ? "": table_message.InitializationErrorString().c_str());
1108
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1109
table_message.InitializationErrorString().c_str());