43
44
#include <drizzled/gettext.h>
44
45
#include <drizzled/unireg.h>
45
46
#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>
47
#include "drizzled/errmsg_print.h"
48
#include "drizzled/xid.h"
49
#include "drizzled/sql_table.h"
50
#include "drizzled/global_charset_info.h"
51
#include "drizzled/charset.h"
52
#include "drizzled/internal/my_sys.h"
53
#include "drizzled/db.h"
53
55
#include <drizzled/table_proto.h>
54
56
#include <drizzled/plugin/event_observer.h>
55
#include <drizzled/internal_error_handler.h>
57
#include <drizzled/table/shell.h>
59
#include <drizzled/message/cache.h>
61
#include <boost/algorithm/string/compare.hpp>
63
58
static bool shutdown_has_begun= false; // Once we put in the container for the vector/etc for engines this will go away.
82
78
return vector_of_schema_engines;
85
StorageEngine::StorageEngine(const std::string name_arg,
86
const std::bitset<HTON_BIT_SIZE> &flags_arg) :
81
StorageEngine::StorageEngine(const string name_arg,
82
const bitset<HTON_BIT_SIZE> &flags_arg) :
87
83
Plugin(name_arg, "StorageEngine"),
88
84
MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
194
190
class FindEngineByName
195
: public std::unary_function<StorageEngine *, bool>
191
: public unary_function<StorageEngine *, bool>
197
const std::string &predicate;
193
const string ⌖
200
explicit FindEngineByName(const std::string &target_arg) :
201
predicate(target_arg)
196
explicit FindEngineByName(const string &target_arg) :
205
200
result_type operator() (argument_type engine)
207
return boost::iequals(engine->getName(), predicate);
202
string engine_name(engine->getName());
204
transform(engine_name.begin(), engine_name.end(),
205
engine_name.begin(), ::tolower);
206
return engine_name == target;
211
StorageEngine *StorageEngine::findByName(const std::string &predicate)
210
StorageEngine *StorageEngine::findByName(const string &find_str)
213
EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
214
vector_of_engines.end(),
215
FindEngineByName(predicate));
212
string search_string(find_str);
213
transform(search_string.begin(), search_string.end(),
214
search_string.begin(), ::tolower);
217
EngineVector::iterator iter= find_if(vector_of_engines.begin(),
218
vector_of_engines.end(),
219
FindEngineByName(search_string));
216
220
if (iter != vector_of_engines.end())
218
222
StorageEngine *engine= *iter;
226
StorageEngine *StorageEngine::findByName(Session& session, const std::string &predicate)
230
StorageEngine *StorageEngine::findByName(Session& session, const string &find_str)
228
if (boost::iequals(predicate, DEFAULT_STRING))
232
string search_string(find_str);
233
transform(search_string.begin(), search_string.end(),
234
search_string.begin(), ::tolower);
236
if (search_string.compare("default") == 0)
229
237
return session.getDefaultStorageEngine();
231
EngineVector::iterator iter= std::find_if(vector_of_engines.begin(),
232
vector_of_engines.end(),
233
FindEngineByName(predicate));
239
EngineVector::iterator iter= find_if(vector_of_engines.begin(),
240
vector_of_engines.end(),
241
FindEngineByName(search_string));
234
242
if (iter != vector_of_engines.end())
236
244
StorageEngine *engine= *iter;
264
272
void StorageEngine::closeConnection(Session* session)
266
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
267
StorageEngineCloseConnection(session));
274
for_each(vector_of_engines.begin(), vector_of_engines.end(),
275
StorageEngineCloseConnection(session));
270
278
bool StorageEngine::flushLogs(StorageEngine *engine)
272
280
if (engine == NULL)
274
if (std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
275
std::mem_fun(&StorageEngine::flush_logs))
282
if (find_if(vector_of_engines.begin(), vector_of_engines.end(),
283
mem_fun(&StorageEngine::flush_logs))
276
284
!= vector_of_engines.begin())
287
class StorageEngineGetTableDefinition: public std::unary_function<StorageEngine *,bool>
295
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
289
297
Session& session;
290
const identifier::Table &identifier;
298
const TableIdentifier &identifier;
291
299
message::Table &table_message;
292
drizzled::error_t &err;
295
303
StorageEngineGetTableDefinition(Session& session_arg,
296
const identifier::Table &identifier_arg,
304
const TableIdentifier &identifier_arg,
297
305
message::Table &table_message_arg,
298
drizzled::error_t &err_arg) :
299
307
session(session_arg),
300
308
identifier(identifier_arg),
301
309
table_message(table_message_arg),
306
314
int ret= engine->doGetTableDefinition(session, identifier, table_message);
308
316
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);
319
return err == EEXIST || err != ENOENT;
315
class StorageEngineDoesTableExist: public std::unary_function<StorageEngine *, bool>
323
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
317
325
Session& session;
318
const identifier::Table &identifier;
326
const TableIdentifier &identifier;
321
StorageEngineDoesTableExist(Session& session_arg, const identifier::Table &identifier_arg) :
329
StorageEngineDoesTableExist(Session& session_arg, const TableIdentifier &identifier_arg) :
322
330
session(session_arg),
323
331
identifier(identifier_arg)
357
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::identifier::Table&)
365
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::TableIdentifier&)
359
std::cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
367
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)
373
Call this function in order to give the Cursor the possiblity
374
to ask engine if there are any new tables that should be written to disk
375
or any dropped tables that need to be removed from disk
377
int StorageEngine::getTableDefinition(Session& session,
378
const TableIdentifier &identifier,
379
message::Table &table_message,
380
bool include_temporary_tables)
368
drizzled::error_t error;
369
error= static_cast<drizzled::error_t>(ENOENT);
371
384
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;
386
if (session.doGetTableDefinition(identifier, table_message) == EEXIST)
387
390
EngineVector::iterator iter=
388
std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
389
StorageEngineGetTableDefinition(session, identifier, message, error));
391
find_if(vector_of_engines.begin(), vector_of_engines.end(),
392
StorageEngineGetTableDefinition(session, identifier, table_message, err));
391
394
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)
433
returns ENOENT if the file doesn't exists.
435
int StorageEngine::dropTable(Session& session,
436
const TableIdentifier &identifier)
440
message::Table src_proto;
441
StorageEngine *engine;
443
error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
445
if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
447
string error_message;
449
error_message.append(const_cast<TableIdentifier &>(identifier).getSQLPath());
450
error_message.append(" : ");
451
error_message.append(src_proto.InitializationErrorString());
453
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
455
return ER_CORRUPT_TABLE_DEFINITION;
458
engine= StorageEngine::findByName(session, src_proto.engine().name());
462
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str());
464
return ER_CORRUPT_TABLE_DEFINITION;
467
error= StorageEngine::dropTable(session, *engine, identifier);
469
if (error_proto && error == 0)
475
int StorageEngine::dropTable(Session& session,
476
StorageEngine &engine,
477
const TableIdentifier &identifier)
517
481
engine.setTransactionReadWrite(session);
519
assert(identifier.isTmp());
521
483
if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
554
bool StorageEngine::createTable(Session &session,
555
const identifier::Table &identifier,
556
message::Table& table_message)
509
int StorageEngine::createTable(Session &session,
510
const TableIdentifier &identifier,
511
message::Table& table_message)
558
drizzled::error_t error= EE_OK;
560
515
TableShare share(identifier);
561
table::Shell table(share);
562
516
message::Table tmp_proto;
564
518
if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
566
520
// @note Error occured, we should probably do a little more here.
567
// ER_CORRUPT_TABLE_DEFINITION,ER_CORRUPT_TABLE_DEFINITION_ENUM
569
my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN, identifier);
588
537
share.storage_engine->setTransactionReadWrite(session);
590
error= static_cast<drizzled::error_t>(share.storage_engine->doCreateTable(session,
539
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);
547
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
607
550
table.delete_table();
610
return(error == EE_OK);
613
Cursor *StorageEngine::getCursor(Table &arg)
556
Cursor *StorageEngine::getCursor(TableShare &share, memory::Root *alloc)
558
return create(share, alloc);
618
561
class AddTableIdentifier :
619
public std::unary_function<StorageEngine *, void>
562
public unary_function<StorageEngine *, void>
621
564
CachedDirectory &directory;
622
const identifier::Schema &identifier;
623
identifier::Table::vector &set_of_identifiers;
565
const SchemaIdentifier &identifier;
566
TableIdentifiers &set_of_identifiers;
627
AddTableIdentifier(CachedDirectory &directory_arg, const identifier::Schema &identifier_arg, identifier::Table::vector &of_names) :
570
AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
628
571
directory(directory_arg),
629
572
identifier(identifier_arg),
630
573
set_of_identifiers(of_names)
653
599
errno= directory.getError();
654
600
if (errno == ENOENT)
657
schema_identifier.getSQLPath(path);
658
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), path.c_str());
601
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), const_cast<SchemaIdentifier &>(schema_identifier).getSQLPath().c_str());
662
603
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));
608
for_each(vector_of_engines.begin(), vector_of_engines.end(),
609
AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
672
611
session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
675
class DropTable: public std::unary_function<identifier::Table&, bool>
614
class DropTable: public unary_function<TableIdentifier&, bool>
677
616
Session &session;
678
617
StorageEngine *engine;
693
/* This will later be converted to identifier::Tables */
694
class DropTables: public std::unary_function<StorageEngine *, void>
632
/* This will later be converted to TableIdentifiers */
633
class DropTables: public unary_function<StorageEngine *, void>
696
635
Session &session;
697
identifier::Table::vector &table_identifiers;
636
TableIdentifiers &table_identifiers;
701
DropTables(Session &session_arg, identifier::Table::vector &table_identifiers_arg) :
640
DropTables(Session &session_arg, TableIdentifiers &table_identifiers_arg) :
702
641
session(session_arg),
703
642
table_identifiers(table_identifiers_arg)
708
647
// True returning from DropTable means the table has been successfully
709
648
// 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)),
649
table_identifiers.erase(remove_if(table_identifiers.begin(),
650
table_identifiers.end(),
651
DropTable(session, engine)),
713
652
table_identifiers.end());
751
690
message::Table definition;
752
691
if (StorageEngine::readTableFile(path, definition))
754
identifier::Table identifier(definition.schema(), definition.name(), path);
693
TableIdentifier identifier(definition.schema(), definition.name(), path);
755
694
table_identifiers.push_back(identifier);
759
std::for_each(vector_of_engines.begin(), vector_of_engines.end(),
760
DropTables(session, table_identifiers));
698
for_each(vector_of_engines.begin(), vector_of_engines.end(),
699
DropTables(session, table_identifiers));
763
702
Now we just clean up anything that might left over.
765
704
We rescan because some of what might have been there should
766
705
now be all nice and cleaned up.
768
std::set<std::string> all_exts= set_of_table_definition_ext;
707
set<string> all_exts= set_of_table_definition_ext;
770
709
for (EngineVector::iterator iter= vector_of_engines.begin();
771
710
iter != vector_of_engines.end() ; iter++)
801
740
- table->getShare()->path
804
void StorageEngine::print_error(int error, myf errflag, const Table &table) const
806
drizzled::error_t textno= ER_GET_ERRNO;
743
void StorageEngine::print_error(int error, myf errflag, Table &table)
745
print_error(error, errflag, &table);
748
void StorageEngine::print_error(int error, myf errflag, Table *table)
750
int textno= ER_GET_ERRNO;
809
753
textno=ER_OPEN_AS_READONLY;
848
794
String str(key,sizeof(key),system_charset_info);
850
796
/* Table is opened and defined at this point */
851
key_unpack(&str, &table,(uint32_t) key_nr);
797
key_unpack(&str,table,(uint32_t) key_nr);
852
798
max_length= (DRIZZLE_ERRMSG_SIZE-
853
799
(uint32_t) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
854
800
if (str.length() >= max_length)
933
879
textno=ER_TABLE_DEF_CHANGED;
935
881
case HA_ERR_NO_SUCH_TABLE:
937
identifier::Table identifier(table.getShare()->getSchemaName(), table.getShare()->getTableName());
938
my_error(ER_TABLE_UNKNOWN, identifier);
883
my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
884
table->getShare()->getTableName());
941
886
case HA_ERR_RBR_LOGGING_FAILED:
942
887
textno= ER_BINLOG_ROW_LOGGING_FAILED;
944
889
case HA_ERR_DROP_INDEX_FK:
946
892
const char *ptr= "???";
947
uint32_t key_nr= table.get_dup_key(error);
893
uint32_t key_nr= table->get_dup_key(error);
948
894
if ((int) key_nr >= 0)
949
ptr= table.key_info[key_nr].name;
895
ptr= table->key_info[key_nr].name;
950
896
my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
1006
951
Returns true if this is a temporary error
1008
bool StorageEngine::get_error_message(int , String* ) const
953
bool StorageEngine::get_error_message(int , String* )
1014
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, const Table &table) const
959
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, Table &table)
1016
961
/* Write the duplicated key in the error message */
1017
962
char key[MAX_KEY_LENGTH];
1042
int StorageEngine::deleteDefinitionFromPath(const identifier::Table &identifier)
987
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1044
std::string path(identifier.getPath());
989
string path(identifier.getPath());
1046
991
path.append(DEFAULT_DEFINITION_FILE_EXT);
1048
993
return internal::my_delete(path.c_str(), MYF(0));
1051
int StorageEngine::renameDefinitionFromPath(const identifier::Table &dest, const identifier::Table &src)
996
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1053
998
message::Table table_message;
1054
std::string src_path(src.getPath());
1055
std::string dest_path(dest.getPath());
999
string src_path(src.getPath());
1000
string dest_path(dest.getPath());
1057
1002
src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1058
1003
dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1174
1114
@note on success table can be created.
1176
bool StorageEngine::canCreateTable(const identifier::Table &identifier)
1116
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1178
1118
EngineVector::iterator iter=
1179
std::find_if(vector_of_engines.begin(), vector_of_engines.end(),
1180
CanCreateTable(identifier));
1119
find_if(vector_of_engines.begin(), vector_of_engines.end(),
1120
CanCreateTable(identifier));
1182
1122
if (iter == vector_of_engines.end())