43
43
#include <drizzled/gettext.h>
44
44
#include <drizzled/unireg.h>
45
45
#include <drizzled/data_home.h>
46
#include <drizzled/errmsg_print.h>
47
#include <drizzled/xid.h>
48
#include <drizzled/sql_table.h>
49
#include <drizzled/global_charset_info.h>
50
#include <drizzled/charset.h>
51
#include <drizzled/internal/my_sys.h>
46
#include "drizzled/errmsg_print.h"
47
#include "drizzled/xid.h"
48
#include "drizzled/sql_table.h"
49
#include "drizzled/global_charset_info.h"
50
#include "drizzled/charset.h"
51
#include "drizzled/internal/my_sys.h"
52
#include "drizzled/db.h"
53
54
#include <drizzled/table_proto.h>
54
55
#include <drizzled/plugin/event_observer.h>
55
#include <drizzled/internal_error_handler.h>
57
57
#include <drizzled/table/shell.h>
59
#include <drizzled/message/cache.h>
61
59
#include <boost/algorithm/string/compare.hpp>
63
61
static bool shutdown_has_begun= false; // Once we put in the container for the vector/etc for engines this will go away.
82
82
return vector_of_schema_engines;
85
StorageEngine::StorageEngine(const std::string name_arg,
86
const std::bitset<HTON_BIT_SIZE> &flags_arg) :
85
StorageEngine::StorageEngine(const string name_arg,
86
const bitset<HTON_BIT_SIZE> &flags_arg) :
87
87
Plugin(name_arg, "StorageEngine"),
88
88
MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
226
StorageEngine *StorageEngine::findByName(Session& session, const std::string &predicate)
226
StorageEngine *StorageEngine::findByName(Session& session, const string &predicate)
228
228
if (boost::iequals(predicate, DEFAULT_STRING))
229
229
return session.getDefaultStorageEngine();
231
EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
232
vector_of_engines.end(),
233
FindEngineByName(predicate));
231
EngineVector::iterator iter= find_if(vector_of_engines.begin(),
232
vector_of_engines.end(),
233
FindEngineByName(predicate));
234
234
if (iter != vector_of_engines.end())
236
236
StorageEngine *engine= *iter;
264
264
void StorageEngine::closeConnection(Session* session)
266
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
267
StorageEngineCloseConnection(session));
266
for_each(vector_of_engines.begin(), vector_of_engines.end(),
267
StorageEngineCloseConnection(session));
270
270
bool StorageEngine::flushLogs(StorageEngine *engine)
272
272
if (engine == NULL)
274
if (std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
std::mem_fun(&StorageEngine::flush_logs))
274
if (find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
mem_fun(&StorageEngine::flush_logs))
276
276
!= vector_of_engines.begin())
287
class StorageEngineGetTableDefinition: public std::unary_function<StorageEngine *,bool>
287
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
289
289
Session& session;
290
const identifier::Table &identifier;
290
const TableIdentifier &identifier;
291
291
message::Table &table_message;
292
drizzled::error_t &err;
295
295
StorageEngineGetTableDefinition(Session& session_arg,
296
const identifier::Table &identifier_arg,
296
const TableIdentifier &identifier_arg,
297
297
message::Table &table_message_arg,
298
drizzled::error_t &err_arg) :
299
299
session(session_arg),
300
300
identifier(identifier_arg),
301
301
table_message(table_message_arg),
306
306
int ret= engine->doGetTableDefinition(session, identifier, table_message);
308
308
if (ret != ENOENT)
309
err= static_cast<drizzled::error_t>(ret);
311
return err == static_cast<drizzled::error_t>(EEXIST) or err != static_cast<drizzled::error_t>(ENOENT);
311
return err == EEXIST || err != ENOENT;
315
class StorageEngineDoesTableExist: public std::unary_function<StorageEngine *, bool>
315
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
317
317
Session& session;
318
const identifier::Table &identifier;
318
const TableIdentifier &identifier;
321
StorageEngineDoesTableExist(Session& session_arg, const identifier::Table &identifier_arg) :
321
StorageEngineDoesTableExist(Session& session_arg, const TableIdentifier &identifier_arg) :
322
322
session(session_arg),
323
323
identifier(identifier_arg)
357
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::identifier::Table&)
357
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::TableIdentifier&)
359
std::cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
359
cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
364
message::table::shared_ptr StorageEngine::getTableMessage(Session& session,
365
identifier::Table::const_reference identifier,
366
bool include_temporary_tables)
365
Call this function in order to give the Cursor the possiblity
366
to ask engine if there are any new tables that should be written to disk
367
or any dropped tables that need to be removed from disk
369
int StorageEngine::getTableDefinition(Session& session,
370
const TableIdentifier &identifier,
371
message::Table &table_message,
372
bool include_temporary_tables)
368
drizzled::error_t error;
369
error= static_cast<drizzled::error_t>(ENOENT);
371
376
if (include_temporary_tables)
373
Table *table= session.find_temporary_table(identifier);
376
return message::table::shared_ptr(new message::Table(*table->getShare()->getTableMessage()));
380
drizzled::message::table::shared_ptr table_ptr;
381
if ((table_ptr= drizzled::message::Cache::singleton().find(identifier)))
386
message::Table message;
378
if (session.doGetTableDefinition(identifier, table_message) == EEXIST)
387
382
EngineVector::iterator iter=
388
std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
389
StorageEngineGetTableDefinition(session, identifier, message, error));
383
find_if(vector_of_engines.begin(), vector_of_engines.end(),
384
StorageEngineGetTableDefinition(session, identifier, table_message, err));
391
386
if (iter == vector_of_engines.end())
393
return message::table::shared_ptr();
395
message::table::shared_ptr table_message(new message::Table(message));
397
drizzled::message::Cache::singleton().insert(identifier, table_message);
399
return table_message;
432
class DropTableByIdentifier: public std::unary_function<EngineVector::value_type, bool>
434
Session::reference session;
435
identifier::Table::const_reference identifier;
436
drizzled::error_t &error;
440
DropTableByIdentifier(Session::reference session_arg,
441
identifier::Table::const_reference identifier_arg,
442
drizzled::error_t &error_arg) :
443
session(session_arg),
444
identifier(identifier_arg),
448
result_type operator() (argument_type engine)
450
if (not engine->doDoesTableExist(session, identifier))
453
int local_error= engine->doDropTable(session, identifier);
461
case HA_ERR_NO_SUCH_TABLE:
463
error= static_cast<drizzled::error_t>(HA_ERR_NO_SUCH_TABLE);
467
error= static_cast<drizzled::error_t>(local_error);
474
bool StorageEngine::dropTable(Session::reference session,
475
identifier::Table::const_reference identifier,
476
drizzled::error_t &error)
480
EngineVector::const_iterator iter= std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
481
DropTableByIdentifier(session, identifier, error));
487
else if (iter == vector_of_engines.end())
489
error= ER_BAD_TABLE_ERROR;
493
drizzled::message::Cache::singleton().erase(identifier);
498
bool StorageEngine::dropTable(Session& session,
499
const identifier::Table &identifier)
501
drizzled::error_t error;
503
if (not dropTable(session, identifier, error))
511
bool StorageEngine::dropTable(Session::reference session,
512
StorageEngine &engine,
513
identifier::Table::const_reference identifier,
514
drizzled::error_t &error)
425
returns ENOENT if the file doesn't exists.
427
int StorageEngine::dropTable(Session& session,
428
const TableIdentifier &identifier)
432
message::Table src_proto;
433
StorageEngine *engine;
435
error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
437
if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
439
string error_message;
441
error_message.append(const_cast<TableIdentifier &>(identifier).getSQLPath());
442
error_message.append(" : ");
443
error_message.append(src_proto.InitializationErrorString());
445
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
447
return ER_CORRUPT_TABLE_DEFINITION;
450
engine= StorageEngine::findByName(session, src_proto.engine().name());
454
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str());
456
return ER_CORRUPT_TABLE_DEFINITION;
459
error= StorageEngine::dropTable(session, *engine, identifier);
461
if (error_proto && error == 0)
467
int StorageEngine::dropTable(Session& session,
468
StorageEngine &engine,
469
const TableIdentifier &identifier)
517
473
engine.setTransactionReadWrite(session);
519
assert(identifier.isTmp());
521
475
if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
554
bool StorageEngine::createTable(Session &session,
555
const identifier::Table &identifier,
556
message::Table& table_message)
501
int StorageEngine::createTable(Session &session,
502
const TableIdentifier &identifier,
503
message::Table& table_message)
558
drizzled::error_t error= EE_OK;
560
506
TableShare share(identifier);
561
507
table::Shell table(share);
562
508
message::Table tmp_proto;
588
529
share.storage_engine->setTransactionReadWrite(session);
590
error= static_cast<drizzled::error_t>(share.storage_engine->doCreateTable(session,
531
error= share.storage_engine->doCreateTable(session,
596
if (error == ER_TABLE_PERMISSION_DENIED)
598
my_error(ER_TABLE_PERMISSION_DENIED, identifier);
603
identifier.getSQLPath(path);
604
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), path.c_str(), error);
539
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
607
542
table.delete_table();
610
return(error == EE_OK);
613
548
Cursor *StorageEngine::getCursor(Table &arg)
618
553
class AddTableIdentifier :
619
public std::unary_function<StorageEngine *, void>
554
public unary_function<StorageEngine *, void>
621
556
CachedDirectory &directory;
622
const identifier::Schema &identifier;
623
identifier::Table::vector &set_of_identifiers;
557
const SchemaIdentifier &identifier;
558
TableIdentifiers &set_of_identifiers;
627
AddTableIdentifier(CachedDirectory &directory_arg, const identifier::Schema &identifier_arg, identifier::Table::vector &of_names) :
562
AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
628
563
directory(directory_arg),
629
564
identifier(identifier_arg),
630
565
set_of_identifiers(of_names)
641
void StorageEngine::getIdentifiers(Session &session, const identifier::Schema &schema_identifier, identifier::Table::vector &set_of_identifiers)
576
void StorageEngine::getIdentifiers(Session &session, const SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
578
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
579
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
643
581
CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
645
583
if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
653
591
errno= directory.getError();
654
592
if (errno == ENOENT)
657
schema_identifier.getSQLPath(path);
658
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), path.c_str());
593
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), const_cast<SchemaIdentifier &>(schema_identifier).getSQLPath().c_str());
662
595
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
669
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
670
AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
600
for_each(vector_of_engines.begin(), vector_of_engines.end(),
601
AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
672
603
session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
675
class DropTable: public std::unary_function<identifier::Table&, bool>
606
class DropTable: public unary_function<TableIdentifier&, bool>
677
608
Session &session;
678
609
StorageEngine *engine;
693
/* This will later be converted to identifier::Tables */
694
class DropTables: public std::unary_function<StorageEngine *, void>
624
/* This will later be converted to TableIdentifiers */
625
class DropTables: public unary_function<StorageEngine *, void>
696
627
Session &session;
697
identifier::Table::vector &table_identifiers;
628
TableIdentifiers &table_identifiers;
701
DropTables(Session &session_arg, identifier::Table::vector &table_identifiers_arg) :
632
DropTables(Session &session_arg, TableIdentifiers &table_identifiers_arg) :
702
633
session(session_arg),
703
634
table_identifiers(table_identifiers_arg)
708
639
// True returning from DropTable means the table has been successfully
709
640
// deleted, so it should be removed from the list of tables to drop
710
table_identifiers.erase(std::remove_if(table_identifiers.begin(),
711
table_identifiers.end(),
712
DropTable(session, engine)),
641
table_identifiers.erase(remove_if(table_identifiers.begin(),
642
table_identifiers.end(),
643
DropTable(session, engine)),
713
644
table_identifiers.end());
751
682
message::Table definition;
752
683
if (StorageEngine::readTableFile(path, definition))
754
identifier::Table identifier(definition.schema(), definition.name(), path);
685
TableIdentifier identifier(definition.schema(), definition.name(), path);
755
686
table_identifiers.push_back(identifier);
759
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
760
DropTables(session, table_identifiers));
690
for_each(vector_of_engines.begin(), vector_of_engines.end(),
691
DropTables(session, table_identifiers));
763
694
Now we just clean up anything that might left over.
765
696
We rescan because some of what might have been there should
766
697
now be all nice and cleaned up.
768
std::set<std::string> all_exts= set_of_table_definition_ext;
699
set<string> all_exts= set_of_table_definition_ext;
770
701
for (EngineVector::iterator iter= vector_of_engines.begin();
771
702
iter != vector_of_engines.end() ; iter++)
801
732
- table->getShare()->path
804
void StorageEngine::print_error(int error, myf errflag, const Table &table) const
806
drizzled::error_t textno= ER_GET_ERRNO;
735
void StorageEngine::print_error(int error, myf errflag, Table &table)
737
print_error(error, errflag, &table);
740
void StorageEngine::print_error(int error, myf errflag, Table *table)
742
int textno= ER_GET_ERRNO;
809
745
textno=ER_OPEN_AS_READONLY;
848
786
String str(key,sizeof(key),system_charset_info);
850
788
/* Table is opened and defined at this point */
851
key_unpack(&str, &table,(uint32_t) key_nr);
789
key_unpack(&str,table,(uint32_t) key_nr);
852
790
max_length= (DRIZZLE_ERRMSG_SIZE-
853
791
(uint32_t) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
854
792
if (str.length() >= max_length)
933
871
textno=ER_TABLE_DEF_CHANGED;
935
873
case HA_ERR_NO_SUCH_TABLE:
937
identifier::Table identifier(table.getShare()->getSchemaName(), table.getShare()->getTableName());
938
my_error(ER_TABLE_UNKNOWN, identifier);
875
my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
876
table->getShare()->getTableName());
941
878
case HA_ERR_RBR_LOGGING_FAILED:
942
879
textno= ER_BINLOG_ROW_LOGGING_FAILED;
944
881
case HA_ERR_DROP_INDEX_FK:
946
884
const char *ptr= "???";
947
uint32_t key_nr= table.get_dup_key(error);
885
uint32_t key_nr= table->get_dup_key(error);
948
886
if ((int) key_nr >= 0)
949
ptr= table.key_info[key_nr].name;
887
ptr= table->key_info[key_nr].name;
950
888
my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
1006
943
Returns true if this is a temporary error
1008
bool StorageEngine::get_error_message(int , String* ) const
945
bool StorageEngine::get_error_message(int , String* )
1014
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, const Table &table) const
951
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, Table &table)
1016
953
/* Write the duplicated key in the error message */
1017
954
char key[MAX_KEY_LENGTH];
1042
int StorageEngine::deleteDefinitionFromPath(const identifier::Table &identifier)
979
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1044
std::string path(identifier.getPath());
981
string path(identifier.getPath());
1046
983
path.append(DEFAULT_DEFINITION_FILE_EXT);
1048
985
return internal::my_delete(path.c_str(), MYF(0));
1051
int StorageEngine::renameDefinitionFromPath(const identifier::Table &dest, const identifier::Table &src)
988
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1053
990
message::Table table_message;
1054
std::string src_path(src.getPath());
1055
std::string dest_path(dest.getPath());
991
string src_path(src.getPath());
992
string dest_path(dest.getPath());
1057
994
src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1058
995
dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1174
1106
@note on success table can be created.
1176
bool StorageEngine::canCreateTable(const identifier::Table &identifier)
1108
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1178
1110
EngineVector::iterator iter=
1179
std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1180
CanCreateTable(identifier));
1111
find_if(vector_of_engines.begin(), vector_of_engines.end(),
1112
CanCreateTable(identifier));
1182
1114
if (iter == vector_of_engines.end())