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>
59
#include "drizzled/message/cache.h"
61
61
#include <boost/algorithm/string/compare.hpp>
63
63
static bool shutdown_has_begun= false; // Once we put in the container for the vector/etc for engines this will go away.
226
StorageEngine *StorageEngine::findByName(Session& session, const std::string &predicate)
228
StorageEngine *StorageEngine::findByName(Session& session, const string &predicate)
228
230
if (boost::iequals(predicate, DEFAULT_STRING))
229
231
return session.getDefaultStorageEngine();
231
EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
232
vector_of_engines.end(),
233
FindEngineByName(predicate));
233
EngineVector::iterator iter= find_if(vector_of_engines.begin(),
234
vector_of_engines.end(),
235
FindEngineByName(predicate));
234
236
if (iter != vector_of_engines.end())
236
238
StorageEngine *engine= *iter;
264
266
void StorageEngine::closeConnection(Session* session)
266
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
267
StorageEngineCloseConnection(session));
268
for_each(vector_of_engines.begin(), vector_of_engines.end(),
269
StorageEngineCloseConnection(session));
270
272
bool StorageEngine::flushLogs(StorageEngine *engine)
272
274
if (engine == NULL)
274
if (std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
std::mem_fun(&StorageEngine::flush_logs))
276
if (find_if(vector_of_engines.begin(), vector_of_engines.end(),
277
mem_fun(&StorageEngine::flush_logs))
276
278
!= vector_of_engines.begin())
287
class StorageEngineGetTableDefinition: public std::unary_function<StorageEngine *,bool>
289
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
289
291
Session& session;
290
const identifier::Table &identifier;
292
const TableIdentifier &identifier;
291
293
message::Table &table_message;
292
drizzled::error_t &err;
295
297
StorageEngineGetTableDefinition(Session& session_arg,
296
const identifier::Table &identifier_arg,
298
const TableIdentifier &identifier_arg,
297
299
message::Table &table_message_arg,
298
drizzled::error_t &err_arg) :
299
301
session(session_arg),
300
302
identifier(identifier_arg),
301
303
table_message(table_message_arg),
306
308
int ret= engine->doGetTableDefinition(session, identifier, table_message);
308
310
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);
313
return err == EEXIST || err != ENOENT;
315
class StorageEngineDoesTableExist: public std::unary_function<StorageEngine *, bool>
317
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
317
319
Session& session;
318
const identifier::Table &identifier;
320
const TableIdentifier &identifier;
321
StorageEngineDoesTableExist(Session& session_arg, const identifier::Table &identifier_arg) :
323
StorageEngineDoesTableExist(Session& session_arg, const TableIdentifier &identifier_arg) :
322
324
session(session_arg),
323
325
identifier(identifier_arg)
357
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::identifier::Table&)
359
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::TableIdentifier&)
359
std::cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
361
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)
367
Call this function in order to give the Cursor the possiblity
368
to ask engine if there are any new tables that should be written to disk
369
or any dropped tables that need to be removed from disk
371
int StorageEngine::getTableDefinition(Session& session,
372
const TableIdentifier &identifier,
373
message::table::shared_ptr &table_message,
374
bool include_temporary_tables)
368
drizzled::error_t error;
369
error= static_cast<drizzled::error_t>(ENOENT);
371
378
if (include_temporary_tables)
373
380
Table *table= session.find_temporary_table(identifier);
376
return message::table::shared_ptr(new message::Table(*table->getShare()->getTableMessage()));
383
table_message.reset(new message::Table(*table->getShare()->getTableProto()));
380
388
drizzled::message::table::shared_ptr table_ptr;
381
389
if ((table_ptr= drizzled::message::Cache::singleton().find(identifier)))
391
table_message= table_ptr;
386
394
message::Table message;
387
395
EngineVector::iterator iter=
388
std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
389
StorageEngineGetTableDefinition(session, identifier, message, error));
396
find_if(vector_of_engines.begin(), vector_of_engines.end(),
397
StorageEngineGetTableDefinition(session, identifier, message, err));
391
399
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;
403
table_message.reset(new message::Table(message));
405
drizzled::message::Cache::singleton().insert(identifier, 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)
441
returns ENOENT if the file doesn't exists.
443
int StorageEngine::dropTable(Session& session,
444
const TableIdentifier &identifier)
448
message::table::shared_ptr src_proto;
449
StorageEngine *engine;
451
error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
453
if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
455
string error_message;
457
error_message.append(const_cast<TableIdentifier &>(identifier).getSQLPath());
458
error_message.append(" : ");
459
error_message.append(src_proto->InitializationErrorString());
461
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
463
return ER_CORRUPT_TABLE_DEFINITION;
467
engine= StorageEngine::findByName(session, src_proto->engine().name());
469
engine= StorageEngine::findByName(session, "");
473
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str());
475
return ER_CORRUPT_TABLE_DEFINITION;
478
error= StorageEngine::dropTable(session, *engine, identifier);
480
if (error_proto && error == 0)
486
int StorageEngine::dropTable(Session& session,
487
StorageEngine &engine,
488
const TableIdentifier &identifier)
517
492
engine.setTransactionReadWrite(session);
519
assert(identifier.isTmp());
521
494
if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
554
bool StorageEngine::createTable(Session &session,
555
const identifier::Table &identifier,
556
message::Table& table_message)
521
int StorageEngine::createTable(Session &session,
522
const TableIdentifier &identifier,
523
message::Table& table_message)
558
drizzled::error_t error= EE_OK;
560
526
TableShare share(identifier);
561
527
table::Shell table(share);
562
528
message::Table tmp_proto;
588
549
share.storage_engine->setTransactionReadWrite(session);
590
error= static_cast<drizzled::error_t>(share.storage_engine->doCreateTable(session,
551
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);
559
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
607
562
table.delete_table();
610
return(error == EE_OK);
613
568
Cursor *StorageEngine::getCursor(Table &arg)
618
573
class AddTableIdentifier :
619
public std::unary_function<StorageEngine *, void>
574
public unary_function<StorageEngine *, void>
621
576
CachedDirectory &directory;
622
const identifier::Schema &identifier;
623
identifier::Table::vector &set_of_identifiers;
577
const SchemaIdentifier &identifier;
578
TableIdentifiers &set_of_identifiers;
627
AddTableIdentifier(CachedDirectory &directory_arg, const identifier::Schema &identifier_arg, identifier::Table::vector &of_names) :
582
AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
628
583
directory(directory_arg),
629
584
identifier(identifier_arg),
630
585
set_of_identifiers(of_names)
653
611
errno= directory.getError();
654
612
if (errno == ENOENT)
657
schema_identifier.getSQLPath(path);
658
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), path.c_str());
613
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), const_cast<SchemaIdentifier &>(schema_identifier).getSQLPath().c_str());
662
615
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));
620
for_each(vector_of_engines.begin(), vector_of_engines.end(),
621
AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
672
623
session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
675
class DropTable: public std::unary_function<identifier::Table&, bool>
626
class DropTable: public unary_function<TableIdentifier&, bool>
677
628
Session &session;
678
629
StorageEngine *engine;
693
/* This will later be converted to identifier::Tables */
694
class DropTables: public std::unary_function<StorageEngine *, void>
644
/* This will later be converted to TableIdentifiers */
645
class DropTables: public unary_function<StorageEngine *, void>
696
647
Session &session;
697
identifier::Table::vector &table_identifiers;
648
TableIdentifiers &table_identifiers;
701
DropTables(Session &session_arg, identifier::Table::vector &table_identifiers_arg) :
652
DropTables(Session &session_arg, TableIdentifiers &table_identifiers_arg) :
702
653
session(session_arg),
703
654
table_identifiers(table_identifiers_arg)
708
659
// True returning from DropTable means the table has been successfully
709
660
// 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)),
661
table_identifiers.erase(remove_if(table_identifiers.begin(),
662
table_identifiers.end(),
663
DropTable(session, engine)),
713
664
table_identifiers.end());
751
702
message::Table definition;
752
703
if (StorageEngine::readTableFile(path, definition))
754
identifier::Table identifier(definition.schema(), definition.name(), path);
705
TableIdentifier identifier(definition.schema(), definition.name(), path);
755
706
table_identifiers.push_back(identifier);
759
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
760
DropTables(session, table_identifiers));
710
for_each(vector_of_engines.begin(), vector_of_engines.end(),
711
DropTables(session, table_identifiers));
763
714
Now we just clean up anything that might left over.
765
716
We rescan because some of what might have been there should
766
717
now be all nice and cleaned up.
768
std::set<std::string> all_exts= set_of_table_definition_ext;
719
set<string> all_exts= set_of_table_definition_ext;
770
721
for (EngineVector::iterator iter= vector_of_engines.begin();
771
722
iter != vector_of_engines.end() ; iter++)
801
752
- table->getShare()->path
804
void StorageEngine::print_error(int error, myf errflag, const Table &table) const
806
drizzled::error_t textno= ER_GET_ERRNO;
755
void StorageEngine::print_error(int error, myf errflag, Table &table)
757
print_error(error, errflag, &table);
760
void StorageEngine::print_error(int error, myf errflag, Table *table)
762
int textno= ER_GET_ERRNO;
809
765
textno=ER_OPEN_AS_READONLY;
848
806
String str(key,sizeof(key),system_charset_info);
850
808
/* Table is opened and defined at this point */
851
key_unpack(&str, &table,(uint32_t) key_nr);
809
key_unpack(&str,table,(uint32_t) key_nr);
852
810
max_length= (DRIZZLE_ERRMSG_SIZE-
853
811
(uint32_t) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
854
812
if (str.length() >= max_length)
933
891
textno=ER_TABLE_DEF_CHANGED;
935
893
case HA_ERR_NO_SUCH_TABLE:
937
identifier::Table identifier(table.getShare()->getSchemaName(), table.getShare()->getTableName());
938
my_error(ER_TABLE_UNKNOWN, identifier);
895
my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
896
table->getShare()->getTableName());
941
898
case HA_ERR_RBR_LOGGING_FAILED:
942
899
textno= ER_BINLOG_ROW_LOGGING_FAILED;
944
901
case HA_ERR_DROP_INDEX_FK:
946
904
const char *ptr= "???";
947
uint32_t key_nr= table.get_dup_key(error);
905
uint32_t key_nr= table->get_dup_key(error);
948
906
if ((int) key_nr >= 0)
949
ptr= table.key_info[key_nr].name;
907
ptr= table->key_info[key_nr].name;
950
908
my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
1006
963
Returns true if this is a temporary error
1008
bool StorageEngine::get_error_message(int , String* ) const
965
bool StorageEngine::get_error_message(int , String* )
1014
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, const Table &table) const
971
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, Table &table)
1016
973
/* Write the duplicated key in the error message */
1017
974
char key[MAX_KEY_LENGTH];
1042
int StorageEngine::deleteDefinitionFromPath(const identifier::Table &identifier)
999
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1044
std::string path(identifier.getPath());
1001
string path(identifier.getPath());
1046
1003
path.append(DEFAULT_DEFINITION_FILE_EXT);
1048
1005
return internal::my_delete(path.c_str(), MYF(0));
1051
int StorageEngine::renameDefinitionFromPath(const identifier::Table &dest, const identifier::Table &src)
1008
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1053
1010
message::Table table_message;
1054
std::string src_path(src.getPath());
1055
std::string dest_path(dest.getPath());
1011
string src_path(src.getPath());
1012
string dest_path(dest.getPath());
1057
1014
src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1058
1015
dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1174
1126
@note on success table can be created.
1176
bool StorageEngine::canCreateTable(const identifier::Table &identifier)
1128
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1178
1130
EngineVector::iterator iter=
1179
std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1180
CanCreateTable(identifier));
1131
find_if(vector_of_engines.begin(), vector_of_engines.end(),
1132
CanCreateTable(identifier));
1182
1134
if (iter == vector_of_engines.end())