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)
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);
539
public unary_function<StorageEngine *, void>
541
CachedDirectory &directory;
542
SchemaIdentifier &identifier;
543
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);
575
560
class AddTableIdentifier :
576
public std::unary_function<StorageEngine *, void>
561
public unary_function<StorageEngine *, void>
578
563
CachedDirectory &directory;
579
const SchemaIdentifier &identifier;
580
TableIdentifier::vector &set_of_identifiers;
564
SchemaIdentifier &identifier;
565
TableIdentifiers &set_of_identifiers;
584
AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifier::vector &of_names) :
569
AddTableIdentifier(CachedDirectory &directory_arg, SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
585
570
directory(directory_arg),
586
571
identifier(identifier_arg),
587
572
set_of_identifiers(of_names)
598
void StorageEngine::getIdentifiers(Session &session, const SchemaIdentifier &schema_identifier, TableIdentifier::vector &set_of_identifiers)
600
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
601
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
603
CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
605
if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
607
else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
611
if (directory.fail())
613
errno= directory.getError();
617
schema_identifier.getSQLPath(path);
618
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), path.c_str());
622
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));
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));
632
637
session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
635
class DropTable: public std::unary_function<TableIdentifier&, bool>
640
class DropTable: public unary_function<TableIdentifier&, bool>
637
642
Session &session;
638
643
StorageEngine *engine;
653
658
/* This will later be converted to TableIdentifiers */
654
class DropTables: public std::unary_function<StorageEngine *, void>
659
class DropTables: public unary_function<StorageEngine *, void>
656
661
Session &session;
657
TableIdentifier::vector &table_identifiers;
662
TableIdentifierList &table_identifiers;
661
DropTables(Session &session_arg, TableIdentifier::vector &table_identifiers_arg) :
666
DropTables(Session &session_arg, TableIdentifierList &table_identifiers_arg) :
662
667
session(session_arg),
663
668
table_identifiers(table_identifiers_arg)
668
673
// True returning from DropTable means the table has been successfully
669
674
// 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)),
675
table_identifiers.erase(remove_if(table_identifiers.begin(),
676
table_identifiers.end(),
677
DropTable(session, engine)),
673
678
table_identifiers.end());
719
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
720
DropTables(session, table_identifiers));
724
for_each(vector_of_engines.begin(), vector_of_engines.end(),
725
DropTables(session, table_identifiers));
723
728
Now we just clean up anything that might left over.
725
730
We rescan because some of what might have been there should
726
731
now be all nice and cleaned up.
728
std::set<std::string> all_exts= set_of_table_definition_ext;
733
set<string> all_exts= set_of_table_definition_ext;
730
735
for (EngineVector::iterator iter= vector_of_engines.begin();
731
736
iter != vector_of_engines.end() ; iter++)
902
914
case HA_ERR_NO_SUCH_TABLE:
904
my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
905
table->getShare()->getTableName());
916
my_error(ER_NO_SUCH_TABLE, MYF(0), table->s->getSchemaName(),
917
table->s->table_name.str);
907
919
case HA_ERR_RBR_LOGGING_FAILED:
908
920
textno= ER_BINLOG_ROW_LOGGING_FAILED;
1008
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1020
int StorageEngine::deleteDefinitionFromPath(TableIdentifier &identifier)
1010
std::string path(identifier.getPath());
1022
string path(identifier.getPath());
1012
1024
path.append(DEFAULT_DEFINITION_FILE_EXT);
1014
1026
return internal::my_delete(path.c_str(), MYF(0));
1017
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1029
int StorageEngine::renameDefinitionFromPath(TableIdentifier &dest, TableIdentifier &src)
1019
1031
message::Table table_message;
1020
std::string src_path(src.getPath());
1021
std::string dest_path(dest.getPath());
1032
string src_path(src.getPath());
1033
string dest_path(dest.getPath());
1023
1035
src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1024
1036
dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1136
1137
@note on success table can be created.
1138
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1139
bool StorageEngine::canCreateTable(drizzled::TableIdentifier &identifier)
1140
1141
EngineVector::iterator iter=
1141
std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1142
CanCreateTable(identifier));
1142
find_if(vector_of_engines.begin(), vector_of_engines.end(),
1143
CanCreateTable(identifier));
1144
1145
if (iter == vector_of_engines.end())
1152
1153
bool StorageEngine::readTableFile(const std::string &path, message::Table &table_message)
1154
std::fstream input(path.c_str(), std::ios::in | std::ios::binary);
1155
fstream input(path.c_str(), ios::in | ios::binary);
1156
1157
if (input.good())
1159
if (table_message.ParseFromIstream(&input))
1159
if (table_message.ParseFromIstream(&input))
1166
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1167
table_message.InitializationErrorString().empty() ? "": table_message.InitializationErrorString().c_str());
1164
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1165
table_message.InitializationErrorString().c_str());