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"
52
#include "drizzled/db.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>
54
53
#include <drizzled/table_proto.h>
55
54
#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>
59
61
#include <boost/algorithm/string/compare.hpp>
61
63
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 string name_arg,
86
const bitset<HTON_BIT_SIZE> &flags_arg) :
85
StorageEngine::StorageEngine(const std::string name_arg,
86
const std::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 string &predicate)
226
StorageEngine *StorageEngine::findByName(Session& session, const std::string &predicate)
228
228
if (boost::iequals(predicate, DEFAULT_STRING))
229
229
return session.getDefaultStorageEngine();
231
EngineVector::iterator iter= find_if(vector_of_engines.begin(),
232
vector_of_engines.end(),
233
FindEngineByName(predicate));
231
EngineVector::iterator iter= std::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
for_each(vector_of_engines.begin(), vector_of_engines.end(),
267
StorageEngineCloseConnection(session));
266
std::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 (find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
mem_fun(&StorageEngine::flush_logs))
274
if (std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
std::mem_fun(&StorageEngine::flush_logs))
276
276
!= vector_of_engines.begin())
287
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
287
class StorageEngineGetTableDefinition: public std::unary_function<StorageEngine *,bool>
289
289
Session& session;
290
const TableIdentifier &identifier;
290
const identifier::Table &identifier;
291
291
message::Table &table_message;
292
drizzled::error_t &err;
295
295
StorageEngineGetTableDefinition(Session& session_arg,
296
const TableIdentifier &identifier_arg,
296
const identifier::Table &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 == EEXIST || err != ENOENT;
311
return err == static_cast<drizzled::error_t>(EEXIST) or err != static_cast<drizzled::error_t>(ENOENT);
315
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
315
class StorageEngineDoesTableExist: public std::unary_function<StorageEngine *, bool>
317
317
Session& session;
318
const TableIdentifier &identifier;
318
const identifier::Table &identifier;
321
StorageEngineDoesTableExist(Session& session_arg, const TableIdentifier &identifier_arg) :
321
StorageEngineDoesTableExist(Session& session_arg, const identifier::Table &identifier_arg) :
322
322
session(session_arg),
323
323
identifier(identifier_arg)
357
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::TableIdentifier&)
357
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::identifier::Table&)
359
cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
359
std::cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
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)
364
message::table::shared_ptr StorageEngine::getTableMessage(Session& session,
365
identifier::Table::const_reference identifier,
366
bool include_temporary_tables)
368
drizzled::error_t error;
369
error= static_cast<drizzled::error_t>(ENOENT);
376
371
if (include_temporary_tables)
378
if (session.doGetTableDefinition(identifier, table_message) == EEXIST)
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;
382
387
EngineVector::iterator iter=
383
find_if(vector_of_engines.begin(), vector_of_engines.end(),
384
StorageEngineGetTableDefinition(session, identifier, table_message, err));
388
std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
389
StorageEngineGetTableDefinition(session, identifier, message, error));
386
391
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;
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)
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)
473
517
engine.setTransactionReadWrite(session);
519
assert(identifier.isTmp());
475
521
if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
501
int StorageEngine::createTable(Session &session,
502
const TableIdentifier &identifier,
503
message::Table& table_message)
554
bool StorageEngine::createTable(Session &session,
555
const identifier::Table &identifier,
556
message::Table& table_message)
558
drizzled::error_t error= EE_OK;
506
560
TableShare share(identifier);
507
561
table::Shell table(share);
508
562
message::Table tmp_proto;
529
588
share.storage_engine->setTransactionReadWrite(session);
531
error= share.storage_engine->doCreateTable(session,
590
error= static_cast<drizzled::error_t>(share.storage_engine->doCreateTable(session,
539
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
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);
542
607
table.delete_table();
610
return(error == EE_OK);
548
613
Cursor *StorageEngine::getCursor(Table &arg)
553
618
class AddTableIdentifier :
554
public unary_function<StorageEngine *, void>
619
public std::unary_function<StorageEngine *, void>
556
621
CachedDirectory &directory;
557
const SchemaIdentifier &identifier;
558
TableIdentifiers &set_of_identifiers;
622
const identifier::Schema &identifier;
623
identifier::Table::vector &set_of_identifiers;
562
AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
627
AddTableIdentifier(CachedDirectory &directory_arg, const identifier::Schema &identifier_arg, identifier::Table::vector &of_names) :
563
628
directory(directory_arg),
564
629
identifier(identifier_arg),
565
630
set_of_identifiers(of_names)
576
void StorageEngine::getIdentifiers(Session &session, const SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
641
void StorageEngine::getIdentifiers(Session &session, const identifier::Schema &schema_identifier, identifier::Table::vector &set_of_identifiers)
578
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
579
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
581
643
CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
583
645
if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
591
653
errno= directory.getError();
592
654
if (errno == ENOENT)
593
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), const_cast<SchemaIdentifier &>(schema_identifier).getSQLPath().c_str());
657
schema_identifier.getSQLPath(path);
658
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), path.c_str());
595
662
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
600
for_each(vector_of_engines.begin(), vector_of_engines.end(),
601
AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
669
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
670
AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
603
672
session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
606
class DropTable: public unary_function<TableIdentifier&, bool>
675
class DropTable: public std::unary_function<identifier::Table&, bool>
608
677
Session &session;
609
678
StorageEngine *engine;
624
/* This will later be converted to TableIdentifiers */
625
class DropTables: public unary_function<StorageEngine *, void>
693
/* This will later be converted to identifier::Tables */
694
class DropTables: public std::unary_function<StorageEngine *, void>
627
696
Session &session;
628
TableIdentifiers &table_identifiers;
697
identifier::Table::vector &table_identifiers;
632
DropTables(Session &session_arg, TableIdentifiers &table_identifiers_arg) :
701
DropTables(Session &session_arg, identifier::Table::vector &table_identifiers_arg) :
633
702
session(session_arg),
634
703
table_identifiers(table_identifiers_arg)
639
708
// True returning from DropTable means the table has been successfully
640
709
// deleted, so it should be removed from the list of tables to drop
641
table_identifiers.erase(remove_if(table_identifiers.begin(),
642
table_identifiers.end(),
643
DropTable(session, engine)),
710
table_identifiers.erase(std::remove_if(table_identifiers.begin(),
711
table_identifiers.end(),
712
DropTable(session, engine)),
644
713
table_identifiers.end());
682
751
message::Table definition;
683
752
if (StorageEngine::readTableFile(path, definition))
685
TableIdentifier identifier(definition.schema(), definition.name(), path);
754
identifier::Table identifier(definition.schema(), definition.name(), path);
686
755
table_identifiers.push_back(identifier);
690
for_each(vector_of_engines.begin(), vector_of_engines.end(),
691
DropTables(session, table_identifiers));
759
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
760
DropTables(session, table_identifiers));
694
763
Now we just clean up anything that might left over.
696
765
We rescan because some of what might have been there should
697
766
now be all nice and cleaned up.
699
set<string> all_exts= set_of_table_definition_ext;
768
std::set<std::string> all_exts= set_of_table_definition_ext;
701
770
for (EngineVector::iterator iter= vector_of_engines.begin();
702
771
iter != vector_of_engines.end() ; iter++)
732
801
- table->getShare()->path
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;
804
void StorageEngine::print_error(int error, myf errflag, const Table &table) const
806
drizzled::error_t textno= ER_GET_ERRNO;
745
809
textno=ER_OPEN_AS_READONLY;
786
848
String str(key,sizeof(key),system_charset_info);
788
850
/* Table is opened and defined at this point */
789
key_unpack(&str,table,(uint32_t) key_nr);
851
key_unpack(&str, &table,(uint32_t) key_nr);
790
852
max_length= (DRIZZLE_ERRMSG_SIZE-
791
853
(uint32_t) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
792
854
if (str.length() >= max_length)
871
933
textno=ER_TABLE_DEF_CHANGED;
873
935
case HA_ERR_NO_SUCH_TABLE:
875
my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
876
table->getShare()->getTableName());
937
identifier::Table identifier(table.getShare()->getSchemaName(), table.getShare()->getTableName());
938
my_error(ER_TABLE_UNKNOWN, identifier);
878
941
case HA_ERR_RBR_LOGGING_FAILED:
879
942
textno= ER_BINLOG_ROW_LOGGING_FAILED;
881
944
case HA_ERR_DROP_INDEX_FK:
884
946
const char *ptr= "???";
885
uint32_t key_nr= table->get_dup_key(error);
947
uint32_t key_nr= table.get_dup_key(error);
886
948
if ((int) key_nr >= 0)
887
ptr= table->key_info[key_nr].name;
949
ptr= table.key_info[key_nr].name;
888
950
my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
943
1006
Returns true if this is a temporary error
945
bool StorageEngine::get_error_message(int , String* )
1008
bool StorageEngine::get_error_message(int , String* ) const
951
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, Table &table)
1014
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, const Table &table) const
953
1016
/* Write the duplicated key in the error message */
954
1017
char key[MAX_KEY_LENGTH];
979
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1042
int StorageEngine::deleteDefinitionFromPath(const identifier::Table &identifier)
981
string path(identifier.getPath());
1044
std::string path(identifier.getPath());
983
1046
path.append(DEFAULT_DEFINITION_FILE_EXT);
985
1048
return internal::my_delete(path.c_str(), MYF(0));
988
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1051
int StorageEngine::renameDefinitionFromPath(const identifier::Table &dest, const identifier::Table &src)
990
1053
message::Table table_message;
991
string src_path(src.getPath());
992
string dest_path(dest.getPath());
1054
std::string src_path(src.getPath());
1055
std::string dest_path(dest.getPath());
994
1057
src_path.append(DEFAULT_DEFINITION_FILE_EXT);
995
1058
dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1106
1174
@note on success table can be created.
1108
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1176
bool StorageEngine::canCreateTable(const identifier::Table &identifier)
1110
1178
EngineVector::iterator iter=
1111
find_if(vector_of_engines.begin(), vector_of_engines.end(),
1112
CanCreateTable(identifier));
1179
std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1180
CanCreateTable(identifier));
1114
1182
if (iter == vector_of_engines.end())