73
78
if (two_phase_commit)
81
pthread_mutex_init(&proto_cache_mutex, NULL);
79
85
plugin::StorageEngine::~StorageEngine()
81
87
savepoint_alloc_size-= orig_savepoint_offset;
88
pthread_mutex_destroy(&proto_cache_mutex);
84
void plugin::StorageEngine::setTransactionReadWrite(Session* session)
91
void plugin::StorageEngine::setTransactionReadWrite(Session& session)
86
Ha_trx_info *ha_info= &session->ha_data[getSlot()].ha_info[0];
93
Ha_trx_info *ha_info= &session.ha_data[getSlot()].ha_info[0];
88
95
When a storage engine method is called, the transaction must
89
96
have been started, unless it's a DDL call, for which the
139
int plugin::StorageEngine::deleteTableImplementation(Session *,
140
const string table_path)
146
int plugin::StorageEngine::doDropTable(Session&,
147
const string table_path)
143
150
int enoent_or_zero= ENOENT; // Error if no file was deleted
144
151
char buff[FN_REFLEN];
146
for (const char **ext=bas_ext(); *ext ; ext++)
153
for (const char **ext= bas_ext(); *ext ; ext++)
148
155
fn_format(buff, table_path.c_str(), "", *ext,
149
156
MY_UNPACK_FILENAME|MY_APPEND_EXT);
190
197
_("Couldn't add StorageEngine"));
201
vector_of_engines.push_back(engine);
203
if (engine->check_flag(HTON_BIT_DOES_TRANSACTIONS))
204
vector_of_transactional_engines.push_back(engine);
206
if (engine->getTableDefinotionExt().length())
208
assert(engine->getTableDefinotionExt().length() == MAX_STORAGE_ENGINE_FILE_EXT);
209
set_of_table_definition_ext.insert(engine->getTableDefinotionExt());
196
215
void plugin::StorageEngine::removePlugin(plugin::StorageEngine *engine)
198
217
all_engines.remove(engine);
201
plugin::StorageEngine *plugin::StorageEngine::findByName(Session *session,
218
vector_of_engines.clear();
219
vector_of_transactional_engines.clear();
222
plugin::StorageEngine *plugin::StorageEngine::findByName(string find_str)
224
transform(find_str.begin(), find_str.end(),
225
find_str.begin(), ::tolower);
227
plugin::StorageEngine *engine= all_engines.find(find_str);
229
if (engine && engine->is_user_selectable())
235
plugin::StorageEngine *plugin::StorageEngine::findByName(Session& session,
205
239
transform(find_str.begin(), find_str.end(),
206
240
find_str.begin(), ::tolower);
207
string default_str("default");
208
if (find_str == default_str)
209
return session->getDefaultStorageEngine();
242
if (find_str.compare("default") == 0)
243
return session.getDefaultStorageEngine();
211
245
plugin::StorageEngine *engine= all_engines.find(find_str);
241
275
void plugin::StorageEngine::closeConnection(Session* session)
243
for_each(all_engines.begin(), all_engines.end(),
277
for_each(vector_of_engines.begin(), vector_of_engines.end(),
244
278
StorageEngineCloseConnection(session));
247
281
void plugin::StorageEngine::dropDatabase(char* path)
249
for_each(all_engines.begin(), all_engines.end(),
283
for_each(vector_of_engines.begin(), vector_of_engines.end(),
250
284
bind2nd(mem_fun(&plugin::StorageEngine::drop_database),path));
466
501
int plugin::StorageEngine::startConsistentSnapshot(Session *session)
468
for_each(all_engines.begin(), all_engines.end(),
503
for_each(vector_of_engines.begin(), vector_of_engines.end(),
469
504
bind2nd(mem_fun(&plugin::StorageEngine::start_consistent_snapshot),
474
class StorageEngineGetTableProto: public unary_function<plugin::StorageEngine *,bool>
509
class StorageEngineGetTableDefition: public unary_function<plugin::StorageEngine *,bool>
476
512
const char* path;
514
const char *table_name;
477
516
message::Table *table_proto;
480
StorageEngineGetTableProto(const char* path_arg,
481
message::Table *table_proto_arg,
483
:path(path_arg), table_proto(table_proto_arg), err(err_arg) {}
520
StorageEngineGetTableDefition(Session& session_arg,
521
const char* path_arg,
523
const char *table_name_arg,
524
const bool is_tmp_arg,
525
message::Table *table_proto_arg,
527
session(session_arg),
530
table_name(table_name_arg),
532
table_proto(table_proto_arg),
485
535
result_type operator() (argument_type engine)
487
int ret= engine->getTableProtoImplementation(path, table_proto);
537
int ret= engine->doGetTableDefinition(session,
489
544
if (ret != ENOENT)
520
575
to ask engine if there are any new tables that should be written to disk
521
576
or any dropped tables that need to be removed from disk
523
int plugin::StorageEngine::getTableProto(const char* path,
524
message::Table *table_proto)
578
int plugin::StorageEngine::getTableDefinition(Session& session,
583
message::Table *table_proto)
528
NameMap<plugin::StorageEngine *>::iterator iter=
529
find_if(all_engines.begin(), all_engines.end(),
530
StorageEngineGetTableProto(path, table_proto, &err));
531
if (iter == all_engines.end())
587
vector<plugin::StorageEngine *>::iterator iter=
588
find_if(vector_of_engines.begin(), vector_of_engines.end(),
589
StorageEngineGetTableDefition(session, path, NULL, NULL, true, table_proto, &err));
591
if (iter == vector_of_engines.end())
533
593
string proto_path(path);
534
594
string file_ext(".dfe");
588
class DeleteTableStorageEngine
589
: public unary_function<plugin::StorageEngine *, void>
596
DeleteTableStorageEngine(Session *session_arg, const char *path_arg,
597
Cursor **file_arg, int *error_arg)
598
: session(session_arg), path(path_arg), file(file_arg), dt_error(error_arg) {}
600
result_type operator() (argument_type engine)
602
char tmp_path[FN_REFLEN];
605
if(*dt_error!=ENOENT) /* already deleted table */
611
if (!engine->is_enabled())
614
if ((tmp_file= engine->create(NULL, session->mem_root)))
619
path= engine->checkLowercaseNames(path, tmp_path);
620
const string table_path(path);
621
int tmp_error= engine->doDeleteTable(session, table_path);
623
if (tmp_error != ENOENT)
627
if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
628
delete_table_proto_file(path);
630
tmp_error= delete_table_proto_file(path);
633
*dt_error= tmp_error;
648
649
This should return ENOENT if the file doesn't exists.
649
650
The .frm file will be deleted only if we return 0 or ENOENT
651
int plugin::StorageEngine::deleteTable(Session *session, const char *path,
652
const char *db, const char *alias,
653
bool generate_warning)
652
int plugin::StorageEngine::dropTable(Session& session, const char *path,
653
const char *db, const char *alias,
654
bool generate_warning)
655
TableShare dummy_share;
657
memset(&dummy_table, 0, sizeof(dummy_table));
658
memset(&dummy_share, 0, sizeof(dummy_share));
660
dummy_table.s= &dummy_share;
665
for_each(all_engines.begin(), all_engines.end(),
666
DeleteTableStorageEngine(session, path, &file, &error));
668
if (error == ENOENT) /* proto may be left behind */
669
error= delete_table_proto_file(path);
658
message::Table src_proto;
659
plugin::StorageEngine* engine;
661
error_proto= plugin::StorageEngine::getTableDefinition(session,
668
engine= plugin::StorageEngine::findByName(session,
669
src_proto.engine().name());
673
engine->setTransactionReadWrite(session);
674
error= engine->doDropTable(session, path);
681
if (engine && engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
682
delete_table_proto_file(path);
684
error= delete_table_proto_file(path);
688
if (error_proto && error == 0)
671
691
if (error && generate_warning)
693
TableShare dummy_share;
699
if ((file= engine->create(NULL, session.mem_root)))
702
memset(&dummy_table, 0, sizeof(dummy_table));
703
memset(&dummy_share, 0, sizeof(dummy_share));
704
dummy_table.s= &dummy_share;
674
707
Because file->print_error() use my_error() to generate the error message
675
708
we use an internal error Cursor to intercept it and store the text
687
720
dummy_share.table_name.length= strlen(alias);
688
721
dummy_table.alias= alias;
692
725
file->change_table_ptr(&dummy_table, &dummy_share);
694
session->push_internal_handler(&ha_delete_table_error_handler);
727
session.push_internal_handler(&ha_delete_table_error_handler);
695
728
file->print_error(error, 0);
697
session->pop_internal_handler();
730
session.pop_internal_handler();
700
733
error= -1; /* General form of fail. maybe bad FRM */
703
736
XXX: should we convert *all* errors to warnings here?
704
737
What if the error is fatal?
706
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error,
739
push_warning(&session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error,
707
740
ha_delete_table_error_handler.buff);
716
class DFETableNameIterator: public plugin::TableNameIteratorImplementation
720
uint32_t current_entry;
723
DFETableNameIterator(const string &database)
724
: plugin::TableNameIteratorImplementation(database),
729
~DFETableNameIterator();
731
int next(string *name);
735
DFETableNameIterator::~DFETableNameIterator()
741
int DFETableNameIterator::next(string *name)
743
char uname[NAME_LEN + 1];
746
uint32_t file_name_len;
747
const char *wild= NULL;
752
char path[FN_REFLEN];
754
build_table_filename(path, sizeof(path), db.c_str(), "", false);
756
dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0));
760
if (my_errno == ENOENT)
761
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db.c_str());
763
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno);
773
if (current_entry == dirp->number_off_files)
780
file= dirp->dir_entry + current_entry;
782
ext= fn_rext(file->name);
786
if (my_strcasecmp(system_charset_info, ext, ".dfe") ||
787
is_prefix(file->name, TMP_FILE_PREFIX))
792
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
794
uname[file_name_len]= '\0';
796
if (wild && wild_compare(uname, wild, 0))
807
plugin::TableNameIterator::TableNameIterator(const string &db)
808
: current_implementation(NULL), database(db)
810
engine_iter= all_engines.begin();
811
default_implementation= new DFETableNameIterator(database);
814
plugin::TableNameIterator::~TableNameIterator()
816
delete current_implementation;
817
if (current_implementation != default_implementation)
819
delete default_implementation;
823
int plugin::TableNameIterator::next(string *name)
828
if (current_implementation == NULL)
830
while(current_implementation == NULL &&
831
(engine_iter != all_engines.end()))
833
plugin::StorageEngine *engine= *engine_iter;
834
current_implementation= engine->tableNameIterator(database);
838
if (current_implementation == NULL &&
839
(engine_iter == all_engines.end()))
841
current_implementation= default_implementation;
845
err= current_implementation->next(name);
849
if (current_implementation != default_implementation)
851
delete current_implementation;
852
current_implementation= NULL;
862
Return the default storage engine plugin::StorageEngine for thread
864
defaultStorageEngine(session)
865
@param session current thread
868
pointer to plugin::StorageEngine
870
plugin::StorageEngine *plugin::StorageEngine::defaultStorageEngine(Session *session)
872
if (session->variables.storage_engine)
873
return session->variables.storage_engine;
874
return global_system_variables.storage_engine;
878
747
Initiates table-file and calls appropriate database-creator.
885
int plugin::StorageEngine::createTable(Session *session, const char *path,
754
int plugin::StorageEngine::createTable(Session& session, const char *path,
886
755
const char *db, const char *table_name,
887
HA_CREATE_INFO *create_info,
756
HA_CREATE_INFO& create_info,
888
757
bool update_create_info,
889
message::Table *table_proto)
758
drizzled::message::Table& table_proto, bool proto_used)
893
762
TableShare share(db, 0, table_name, path);
894
763
message::Table tmp_proto;
898
if (parse_table_proto(session, *table_proto, &share))
767
if (parse_table_proto(session, table_proto, &share))
903
table_proto= &tmp_proto;
904
772
if (open_table_def(session, &share))
908
if (open_table_from_share(session, &share, "", 0, (uint32_t) READ_ALL, 0,
776
if (open_table_from_share(&session, &share, "", 0, (uint32_t) READ_ALL, 0,
909
777
&table, OTM_CREATE))
912
780
if (update_create_info)
913
table.updateCreateInfo(create_info, table_proto);
915
error= share.storage_engine->doCreateTable(session, path, &table,
916
create_info, table_proto);
781
table.updateCreateInfo(&create_info, &table_proto);
784
char name_buff[FN_REFLEN];
785
const char *table_name_arg;
787
table_name_arg= share.storage_engine->checkLowercaseNames(path, name_buff);
789
share.storage_engine->setTransactionReadWrite(session);
791
error= share.storage_engine->doCreateTable(&session, table_name_arg, table,
792
create_info, table_proto);
917
795
table.closefrm(false);
819
TODO -> Remove this to force all engines to implement their own file. Solves the "we only looked at dfe" problem.
821
void plugin::StorageEngine::doGetTableNames(CachedDirectory &directory, string&, set<string>& set_of_names)
823
CachedDirectory::Entries entries= directory.getEntries();
825
for (CachedDirectory::Entries::iterator entry_iter= entries.begin();
826
entry_iter != entries.end(); ++entry_iter)
828
CachedDirectory::Entry *entry= *entry_iter;
829
string *filename= &entry->filename;
831
assert(filename->size());
833
const char *ext= strchr(filename->c_str(), '.');
835
if (ext == NULL || my_strcasecmp(system_charset_info, ext, DEFAULT_DEFINITION_FILE_EXT.c_str()) ||
836
is_prefix(filename->c_str(), TMP_FILE_PREFIX))
840
char uname[NAME_LEN + 1];
841
uint32_t file_name_len;
843
file_name_len= filename_to_tablename(filename->c_str(), uname, sizeof(uname));
844
// TODO: Remove need for memory copy here
845
uname[file_name_len - sizeof(".dfe") + 1]= '\0'; // Subtract ending, place NULL
846
set_of_names.insert(uname);
852
public unary_function<plugin::StorageEngine *, void>
855
CachedDirectory& directory;
856
set<string>& set_of_names;
860
AddTableName(CachedDirectory& directory_arg, string& database_name, set<string>& of_names) :
861
directory(directory_arg),
862
set_of_names(of_names)
867
result_type operator() (argument_type engine)
869
engine->doGetTableNames(directory, db, set_of_names);
873
void plugin::StorageEngine::getTableNames(string& db, set<string>& set_of_names)
875
char tmp_path[FN_REFLEN];
877
build_table_filename(tmp_path, sizeof(tmp_path), db.c_str(), "", false);
879
CachedDirectory directory(tmp_path, set_of_table_definition_ext);
881
if (db.compare("information_schema"))
883
if (directory.fail())
885
my_errno= directory.getError();
886
if (my_errno == ENOENT)
887
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db.c_str());
889
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), my_errno);
894
for_each(vector_of_engines.begin(), vector_of_engines.end(),
895
AddTableName(directory, db, set_of_names));
941
899
} /* namespace drizzled */