74
75
static std::set<std::string> set_of_table_definition_ext;
76
77
StorageEngine::StorageEngine(const string name_arg,
77
const bitset<HTON_BIT_SIZE> &flags_arg)
78
: Plugin(name_arg, "StorageEngine"),
79
MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
78
const bitset<HTON_BIT_SIZE> &flags_arg) :
79
Plugin(name_arg, "StorageEngine"),
80
MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
82
pthread_mutex_init(&proto_cache_mutex, NULL);
85
85
StorageEngine::~StorageEngine()
87
pthread_mutex_destroy(&proto_cache_mutex);
90
89
void StorageEngine::setTransactionReadWrite(Session& session)
93
92
statement_ctx.markModifiedNonTransData();
96
int StorageEngine::doRenameTable(Session *,
96
int StorageEngine::renameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
101
for (const char **ext= bas_ext(); *ext ; ext++)
103
if (rename_file_ext(from, to, *ext))
105
if ((error=errno) != ENOENT)
98
setTransactionReadWrite(session);
100
return doRenameTable(session, from, to);
115
104
Delete all files with extension from bas_ext().
202
StorageEngine *StorageEngine::findByName(string find_str)
196
StorageEngine *StorageEngine::findByName(const string &find_str)
204
transform(find_str.begin(), find_str.end(),
205
find_str.begin(), ::tolower);
198
string search_string(find_str);
199
transform(search_string.begin(), search_string.end(),
200
search_string.begin(), ::tolower);
208
203
EngineVector::iterator iter= find_if(vector_of_engines.begin(),
209
204
vector_of_engines.end(),
210
FindEngineByName(find_str));
205
FindEngineByName(search_string));
211
206
if (iter != vector_of_engines.end())
213
208
StorageEngine *engine= *iter;
221
StorageEngine *StorageEngine::findByName(Session& session, string find_str)
216
StorageEngine *StorageEngine::findByName(Session& session, const string &find_str)
224
transform(find_str.begin(), find_str.end(),
225
find_str.begin(), ::tolower);
218
string search_string(find_str);
219
transform(search_string.begin(), search_string.end(),
220
search_string.begin(), ::tolower);
227
if (find_str.compare("default") == 0)
222
if (search_string.compare("default") == 0)
228
223
return session.getDefaultStorageEngine();
230
225
EngineVector::iterator iter= find_if(vector_of_engines.begin(),
231
226
vector_of_engines.end(),
232
FindEngineByName(find_str));
227
FindEngineByName(search_string));
233
228
if (iter != vector_of_engines.end())
235
230
StorageEngine *engine= *iter;
460
452
message::Table src_proto;
461
StorageEngine* engine;
453
StorageEngine *engine;
463
455
error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
465
457
if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
467
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
468
src_proto.InitializationErrorString().c_str());
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());
469
467
return ER_CORRUPT_TABLE_DEFINITION;
476
std::string path(identifier.getPath());
477
engine->setTransactionReadWrite(session);
478
error= engine->doDropTable(session, identifier);
482
if (not engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
484
uint64_t counter; // @todo We need to refactor to check that.
486
for_each(vector_of_schema_engines.begin(), vector_of_schema_engines.end(),
487
DropTable(session, identifier, counter));
474
error= StorageEngine::dropTable(session, *engine, identifier);
492
477
if (error_proto && error == 0)
483
int StorageEngine::dropTable(Session& session,
484
StorageEngine &engine,
485
TableIdentifier &identifier)
489
engine.setTransactionReadWrite(session);
490
error= engine.doDropTable(session, identifier);
494
if (not engine.check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
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));
499
507
Initiates table-file and calls appropriate database-creator.
515
521
TableShare share(identifier.getDBName().c_str(), 0, identifier.getTableName().c_str(), identifier.getPath().c_str());
516
522
message::Table tmp_proto;
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);
524
if (parse_table_proto(session, table_message, &share) || open_table_from_share(&session, &share, "", 0, 0, &table))
526
// @note Error occured, we should probably do a little more here.
530
if (update_create_info)
531
table.updateCreateInfo(&table_message);
533
/* Check for legal operations against the Engine using the proto (if used) */
534
if (table_message.type() == message::Table::TEMPORARY &&
535
share.storage_engine->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED) == true)
537
error= HA_ERR_UNSUPPORTED;
539
else if (table_message.type() != message::Table::TEMPORARY &&
540
share.storage_engine->check_flag(HTON_BIT_TEMPORARY_ONLY) == true)
542
error= HA_ERR_UNSUPPORTED;
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);
574
580
share.free_table_share();
575
581
return(error != 0);
639
645
class StorageEngineGetSchemaDefinition: public unary_function<StorageEngine *, bool>
641
const std::string &schema_name;
647
std::string schema_name;
642
648
message::Schema &schema_proto;
645
StorageEngineGetSchemaDefinition(const std::string &schema_name_arg,
651
StorageEngineGetSchemaDefinition(const std::string schema_name_arg,
646
652
message::Schema &schema_proto_arg) :
647
653
schema_name(schema_name_arg),
648
654
schema_proto(schema_proto_arg)
656
transform(schema_name.begin(), schema_name.end(),
657
schema_name.begin(), ::tolower);
651
660
result_type operator() (argument_type engine)
843
864
class DropTables: public unary_function<StorageEngine *, void>
845
866
Session &session;
846
TableNameList &set_of_names;
867
TableIdentifierList &table_identifiers;
850
DropTables(Session &session_arg, set<string>& of_names) :
871
DropTables(Session &session_arg, TableIdentifierList &table_identifiers_arg) :
851
872
session(session_arg),
852
set_of_names(of_names)
873
table_identifiers(table_identifiers_arg)
855
876
result_type operator() (argument_type engine)
857
for (TableNameList::iterator iter= set_of_names.begin();
858
iter != set_of_names.end();
878
for (TableIdentifierList::iterator iter= table_identifiers.begin();
879
iter != table_identifiers.end();
861
TableIdentifier dummy((*iter).c_str());
862
int error= engine->doDropTable(session, dummy);
882
int error= engine->doDropTable(session, const_cast<TableIdentifier&>(*iter));
864
884
// On a return of zero we know we found and deleted the table. So we
865
885
// remove it from our search.
867
set_of_names.erase(iter);
887
table_identifiers.erase(iter);
903
923
path+= directory;
904
924
path+= FN_LIBCHAR;
905
925
path+= entry->filename;
906
set_of_table_names.insert(path);
926
message::Table definition;
927
if (StorageEngine::readTableFile(path, definition))
929
TableIdentifier identifier(definition.schema(), definition.name(), path);
930
table_identifiers.push_back(identifier);
909
934
for_each(vector_of_engines.begin(), vector_of_engines.end(),
910
DropTables(session, set_of_table_names));
935
DropTables(session, table_identifiers));
913
938
Now we just clean up anything that might left over.
1214
1239
int StorageEngine::renameDefinitionFromPath(TableIdentifier &dest, TableIdentifier &src)
1241
message::Table table_message;
1216
1242
string src_path(src.getPath());
1217
1243
string dest_path(dest.getPath());
1219
1245
src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1220
1246
dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1222
return internal::my_rename(src_path.c_str(), dest_path.c_str(), MYF(MY_WME));
1248
bool was_read= StorageEngine::readTableFile(src_path.c_str(), table_message);
1255
dest.copyToTableMessage(table_message);
1257
int error= StorageEngine::writeDefinitionFromPath(dest, table_message);
1261
if (unlink(src_path.c_str()))
1262
perror(src_path.c_str());
1225
1268
int StorageEngine::writeDefinitionFromPath(TableIdentifier &identifier, message::Table &table_message)
1270
char definition_file_tmp[FN_REFLEN];
1227
1271
string file_name(identifier.getPath());
1229
1273
file_name.append(DEFAULT_DEFINITION_FILE_EXT);
1231
int fd= open(file_name.c_str(), O_RDWR|O_CREAT|O_TRUNC, internal::my_umask);
1275
snprintf(definition_file_tmp, sizeof(definition_file_tmp), "%s.%sXXXXXX", file_name.c_str(), DEFAULT_DEFINITION_FILE_EXT.c_str());
1277
int fd= mkstemp(definition_file_tmp);
1281
perror(definition_file_tmp);
1236
1285
google::protobuf::io::ZeroCopyOutputStream* output=
1237
1286
new google::protobuf::io::FileOutputStream(fd);
1239
if (table_message.SerializeToZeroCopyStream(output) == false)
1288
if (not table_message.SerializeToZeroCopyStream(output))
1290
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1291
table_message.InitializationErrorString().c_str());
1294
if (close(fd) == -1)
1295
perror(definition_file_tmp);
1297
if (unlink(definition_file_tmp) == -1)
1298
perror(definition_file_tmp);
1300
return ER_CORRUPT_TABLE_DEFINITION;
1305
if (close(fd) == -1)
1308
perror(definition_file_tmp);
1310
if (unlink(definition_file_tmp))
1311
perror(definition_file_tmp);
1316
if (rename(definition_file_tmp, file_name.c_str()) == -1)
1319
perror(definition_file_tmp);
1321
if (unlink(definition_file_tmp))
1322
perror(definition_file_tmp);
1363
bool StorageEngine::readTableFile(const std::string &path, message::Table &table_message)
1365
fstream input(path.c_str(), ios::in | ios::binary);
1369
if (table_message.ParseFromIstream(&input))
1374
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1375
table_message.InitializationErrorString().c_str());
1379
perror(path.c_str());
1284
1387
} /* namespace plugin */
1285
1388
} /* namespace drizzled */