72
79
savepoint_alloc_size-= orig_savepoint_offset;
76
/* args: current_session, db, name */
77
int StorageEngine::table_exists_in_engine(Session*, const char *, const char *)
79
return HA_ERR_NO_SUCH_TABLE;
82
82
void StorageEngine::setTransactionReadWrite(Session* session)
84
84
Ha_trx_info *ha_info= &session->ha_data[getSlot()].ha_info[0];
129
129
pointer to storage engine plugin handle
131
StorageEngine *ha_resolve_by_name(Session *session, const LEX_STRING *name)
131
StorageEngine *ha_resolve_by_name(Session *session, std::string find_str)
134
string find_str(name->str, name->length);
135
133
transform(find_str.begin(), find_str.end(),
136
134
find_str.begin(), ::tolower);
137
135
string default_str("default");
138
136
if (find_str == default_str)
139
137
return ha_default_storage_engine(session);
142
139
StorageEngine *engine= all_engines.find(find_str);
428
Ask handler if the table exists in engine.
430
HA_ERR_NO_SUCH_TABLE Table does not exist
432
HA_ERR_TABLE_EXIST Table exists
437
class TableExistsInStorageEngine: public unary_function<StorageEngine *,bool>
424
static int drizzle_read_table_proto(const char* path, drizzled::message::Table* table)
426
int fd= open(path, O_RDONLY);
431
google::protobuf::io::ZeroCopyInputStream* input=
432
new google::protobuf::io::FileInputStream(fd);
434
if (table->ParseFromZeroCopyStream(input) == false)
446
class StorageEngineGetTableProto: public unary_function<StorageEngine *,bool>
449
drizzled::message::Table *table_proto;
443
TableExistsInStorageEngine(Session *session_arg,
444
const char *db_arg, const char *name_arg)
445
:session(session_arg), db(db_arg), name(name_arg) {}
452
StorageEngineGetTableProto(const char* path_arg,
453
drizzled::message::Table *table_proto_arg,
455
:path(path_arg), table_proto(table_proto_arg), err(err_arg) {}
446
457
result_type operator() (argument_type engine)
448
int ret= engine->table_exists_in_engine(session, db, name);
449
return ret == HA_ERR_TABLE_EXIST;
459
int ret= engine->getTableProtoImplementation(path, table_proto);
464
return *err == EEXIST;
455
470
to ask engine if there are any new tables that should be written to disk
456
471
or any dropped tables that need to be removed from disk
458
int ha_table_exists_in_engine(Session* session,
459
const char* db, const char* name,
460
StorageEngine **engine_arg)
473
int StorageEngine::getTableProto(const char* path,
474
drizzled::message::Table *table_proto)
462
StorageEngine *engine= NULL;
465
478
drizzled::Registry<StorageEngine *>::iterator iter=
466
479
find_if(all_engines.begin(), all_engines.end(),
467
TableExistsInStorageEngine(session, db, name));
468
if (iter != all_engines.end())
475
/* Default way of knowing if a table exists. (checking .frm exists) */
477
char path[FN_REFLEN];
479
length= build_table_filename(path, sizeof(path),
482
if ((table_proto_exists(path) == EEXIST))
485
if (found && engine_arg)
480
StorageEngineGetTableProto(path, table_proto, &err));
481
if (iter == all_engines.end())
483
string proto_path(path);
484
string file_ext(".dfe");
485
proto_path.append(file_ext);
487
int error= access(proto_path.c_str(), F_OK);
487
drizzled::message::Table table;
488
strcpy(path + length, ".dfe");
489
if (drizzle_read_table_proto(path, &table) == 0)
491
LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
492
strlen(table.engine().name().c_str()) };
493
engine= ha_resolve_by_name(session, &engine_name);
496
int read_proto_err= drizzle_read_table_proto(proto_path.c_str(),
499
return HA_ERR_NO_SUCH_TABLE;
504
return HA_ERR_TABLE_EXIST;
507
int StorageEngine::renameTableImpl(Session *, const char *from, const char *to)
508
int StorageEngine::renameTableImplementation(Session *, const char *from, const char *to)
510
511
for (const char **ext= bas_ext(); *ext ; ext++)
560
static const char *check_lowercase_names(handler *file, const char *path,
563
if ((file->ha_table_flags() & HA_FILE_BASED))
566
/* Ensure that table handler get path in lower case */
567
if (tmp_path != path)
568
strcpy(tmp_path, path);
571
we only should turn into lowercase database/table part
572
so start the process after homedirectory
574
my_casedn_str(files_charset_info, tmp_path + drizzle_data_home_len);
579
562
An interceptor to hijack the text of the error message without
580
563
setting an error in the thread. We need the text to present it
640
path= check_lowercase_names(tmp_file, path, tmp_path);
623
path= engine->checkLowercaseNames(path, tmp_path);
641
624
const std::string table_path(path);
642
625
int tmp_error= engine->deleteTable(session, table_path);
644
if(tmp_error!=ENOENT)
627
if (tmp_error != ENOENT)
631
if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY))
632
delete_table_proto_file(path);
634
tmp_error= delete_table_proto_file(path);
646
637
*dt_error= tmp_error;
676
667
for_each(all_engines.begin(), all_engines.end(),
677
668
DeleteTableStorageEngine(session, path, &file, &error));
670
if (error == ENOENT) /* proto may be left behind */
671
error= delete_table_proto_file(path);
679
673
if (error && generate_warning)
733
727
int ha_create_table(Session *session, const char *path,
734
728
const char *db, const char *table_name,
735
729
HA_CREATE_INFO *create_info,
736
bool update_create_info)
730
bool update_create_info,
731
drizzled::message::Table *table_proto)
740
char name_buff[FN_REFLEN];
742
735
TableShare share(db, 0, table_name, path);
744
if (open_table_def(session, &share) ||
745
open_table_from_share(session, &share, "", 0, (uint32_t) READ_ALL, 0, &table,
739
if (parse_table_proto(session, *table_proto, &share))
744
if (open_table_def(session, &share))
748
if (open_table_from_share(session, &share, "", 0, (uint32_t) READ_ALL, 0,
749
752
if (update_create_info)
750
753
table.updateCreateInfo(create_info);
752
name= check_lowercase_names(table.file, share.path.str, name_buff);
754
error= share.storage_engine->createTable(session, name, &table, create_info);
755
error= share.storage_engine->createTable(session, path, &table,
756
create_info, table_proto);
755
757
table.closefrm(false);
760
char name_buff[FN_REFLEN];
758
761
sprintf(name_buff,"%s.%s",db,table_name);
759
762
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), name_buff, error);
769
772
return engine == NULL ? string("UNKNOWN") : engine->getName();
775
const char *StorageEngine::checkLowercaseNames(const char *path, char *tmp_path)
777
if (flags.test(HTON_BIT_FILE_BASED))
780
/* Ensure that table handler get path in lower case */
781
if (tmp_path != path)
782
strcpy(tmp_path, path);
785
we only should turn into lowercase database/table part
786
so start the process after homedirectory
788
my_casedn_str(files_charset_info, tmp_path + drizzle_data_home_len);
793
class DFETableNameIterator: public TableNameIteratorImplementation
797
uint32_t current_entry;
800
DFETableNameIterator(const std::string &database)
801
: TableNameIteratorImplementation(database),
806
~DFETableNameIterator();
808
int next(std::string *name);
812
DFETableNameIterator::~DFETableNameIterator()
818
int DFETableNameIterator::next(string *name)
820
char uname[NAME_LEN + 1];
823
uint32_t file_name_len;
824
const char *wild= NULL;
829
char path[FN_REFLEN];
831
build_table_filename(path, sizeof(path), db.c_str(), "", false);
833
dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0));
837
if (my_errno == ENOENT)
838
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db.c_str());
840
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno);
850
if (current_entry == dirp->number_off_files)
857
file= dirp->dir_entry + current_entry;
859
if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),".dfe") ||
860
is_prefix(file->name, TMP_FILE_PREFIX))
864
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
866
uname[file_name_len]= '\0';
868
if (wild && wild_compare(uname, wild, 0))
878
TableNameIterator::TableNameIterator(const std::string &db)
879
: current_implementation(NULL), database(db)
881
engine_iter= all_engines.begin();
882
default_implementation= new DFETableNameIterator(database);
885
TableNameIterator::~TableNameIterator()
887
delete current_implementation;
890
int TableNameIterator::next(std::string *name)
895
if (current_implementation == NULL)
897
while(current_implementation == NULL && engine_iter != all_engines.end())
899
StorageEngine *engine= *engine_iter;
900
current_implementation= engine->tableNameIterator(database);
904
if (current_implementation == NULL && engine_iter == all_engines.end())
906
current_implementation= default_implementation;
910
err= current_implementation->next(name);
914
if (current_implementation != default_implementation)
916
delete current_implementation;
917
current_implementation= NULL;