53
52
#include "drizzled/db.h"
55
54
#include <drizzled/table_proto.h>
55
#include <drizzled/plugin/event_observer.h>
57
#include <drizzled/table/shell.h>
59
#include <boost/algorithm/string/compare.hpp>
57
61
static bool shutdown_has_begun= false; // Once we put in the container for the vector/etc for engines this will go away.
67
71
static EngineVector vector_of_engines;
68
72
static EngineVector vector_of_schema_engines;
74
const std::string DEFAULT_STRING("default");
70
75
const std::string UNKNOWN_STRING("UNKNOWN");
71
76
const std::string DEFAULT_DEFINITION_FILE_EXT(".dfe");
99
int StorageEngine::renameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
104
int StorageEngine::renameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
101
107
setTransactionReadWrite(session);
103
return doRenameTable(session, from, to);
109
if (unlikely(plugin::EventObserver::beforeRenameTable(session, from, to)))
111
error= ER_EVENT_OBSERVER_PLUGIN;
115
error = doRenameTable(session, from, to);
116
if (unlikely(plugin::EventObserver::afterRenameTable(session, from, to, error)))
118
error= ER_EVENT_OBSERVER_PLUGIN;
175
194
class FindEngineByName
176
195
: public unary_function<StorageEngine *, bool>
178
const string ⌖
197
const string &predicate;
181
200
explicit FindEngineByName(const string &target_arg) :
201
predicate(target_arg)
185
205
result_type operator() (argument_type engine)
187
string engine_name(engine->getName());
189
transform(engine_name.begin(), engine_name.end(),
190
engine_name.begin(), ::tolower);
191
return engine_name == target;
207
return boost::iequals(engine->getName(), predicate);
195
StorageEngine *StorageEngine::findByName(const string &find_str)
211
StorageEngine *StorageEngine::findByName(const string &predicate)
197
string search_string(find_str);
198
transform(search_string.begin(), search_string.end(),
199
search_string.begin(), ::tolower);
202
213
EngineVector::iterator iter= find_if(vector_of_engines.begin(),
203
214
vector_of_engines.end(),
204
FindEngineByName(search_string));
215
FindEngineByName(predicate));
205
216
if (iter != vector_of_engines.end())
207
218
StorageEngine *engine= *iter;
215
StorageEngine *StorageEngine::findByName(Session& session, const string &find_str)
226
StorageEngine *StorageEngine::findByName(Session& session, const string &predicate)
217
string search_string(find_str);
218
transform(search_string.begin(), search_string.end(),
219
search_string.begin(), ::tolower);
221
if (search_string.compare("default") == 0)
228
if (boost::iequals(predicate, DEFAULT_STRING))
222
229
return session.getDefaultStorageEngine();
224
231
EngineVector::iterator iter= find_if(vector_of_engines.begin(),
225
232
vector_of_engines.end(),
226
FindEngineByName(search_string));
233
FindEngineByName(predicate));
227
234
if (iter != vector_of_engines.end())
229
236
StorageEngine *engine= *iter;
280
287
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
282
289
Session& session;
283
TableIdentifier &identifier;
290
const TableIdentifier &identifier;
284
291
message::Table &table_message;
288
295
StorageEngineGetTableDefinition(Session& session_arg,
289
TableIdentifier &identifier_arg,
296
const TableIdentifier &identifier_arg,
290
297
message::Table &table_message_arg,
292
299
session(session_arg),
308
315
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
310
317
Session& session;
311
TableIdentifier &identifier;
318
const TableIdentifier &identifier;
314
StorageEngineDoesTableExist(Session& session_arg, TableIdentifier &identifier_arg) :
321
StorageEngineDoesTableExist(Session& session_arg, const TableIdentifier &identifier_arg) :
315
322
session(session_arg),
316
323
identifier(identifier_arg)
326
333
Utility method which hides some of the details of getTableDefinition()
328
335
bool plugin::StorageEngine::doesTableExist(Session &session,
329
TableIdentifier &identifier,
336
const TableIdentifier &identifier,
330
337
bool include_temporary_tables)
332
339
if (include_temporary_tables)
360
367
or any dropped tables that need to be removed from disk
362
369
int StorageEngine::getTableDefinition(Session& session,
363
TableIdentifier &identifier,
370
const TableIdentifier &identifier,
364
371
message::Table &table_message,
365
372
bool include_temporary_tables)
447
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), identifier.getSQLPath().c_str());
454
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str());
449
456
return ER_CORRUPT_TABLE_DEFINITION;
460
467
int StorageEngine::dropTable(Session& session,
461
468
StorageEngine &engine,
462
TableIdentifier &identifier)
469
const TableIdentifier &identifier)
466
473
engine.setTransactionReadWrite(session);
467
error= engine.doDropTable(session, identifier);
475
if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
477
error= ER_EVENT_OBSERVER_PLUGIN;
481
error= engine.doDropTable(session, identifier);
482
if (unlikely(plugin::EventObserver::afterDropTable(session, identifier, error)))
484
error= ER_EVENT_OBSERVER_PLUGIN;
481
501
int StorageEngine::createTable(Session &session,
482
TableIdentifier &identifier,
483
bool update_create_info,
502
const TableIdentifier &identifier,
484
503
message::Table& table_message)
488
TableShare share(identifier.getSchemaName().c_str(), 0, identifier.getTableName().c_str(), identifier.getPath().c_str());
506
TableShare share(identifier);
507
table::Shell table(share);
489
508
message::Table tmp_proto;
491
if (parse_table_proto(session, table_message, &share) || open_table_from_share(&session, &share, "", 0, 0, &table))
510
if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
493
512
// @note Error occured, we should probably do a little more here.
497
if (update_create_info)
498
table.updateCreateInfo(&table_message);
500
516
/* Check for legal operations against the Engine using the proto (if used) */
501
517
if (table_message.type() == message::Table::TEMPORARY &&
502
518
share.storage_engine->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED) == true)
523
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), identifier.getSQLPath().c_str(), error);
539
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
526
table.closefrm(false);
542
table.delete_table();
529
share.free_table_share();
530
545
return(error != 0);
533
Cursor *StorageEngine::getCursor(TableShare &share, memory::Root *alloc)
548
Cursor *StorageEngine::getCursor(TableShare &share)
535
return create(share, alloc);
550
return create(share);
539
public unary_function<StorageEngine *, void>
541
CachedDirectory &directory;
542
SchemaIdentifier &identifier;
543
TableNameList &set_of_names;
547
AddTableName(CachedDirectory &directory_arg, SchemaIdentifier &identifier_arg, set<string>& of_names) :
548
directory(directory_arg),
549
identifier(identifier_arg),
550
set_of_names(of_names)
554
result_type operator() (argument_type engine)
556
engine->doGetTableNames(directory, identifier, set_of_names);
560
553
class AddTableIdentifier :
561
554
public unary_function<StorageEngine *, void>
563
556
CachedDirectory &directory;
564
SchemaIdentifier &identifier;
557
const SchemaIdentifier &identifier;
565
558
TableIdentifiers &set_of_identifiers;
569
AddTableIdentifier(CachedDirectory &directory_arg, SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
562
AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
570
563
directory(directory_arg),
571
564
identifier(identifier_arg),
572
565
set_of_identifiers(of_names)
583
static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
584
static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
586
void StorageEngine::getTableNames(Session &session, SchemaIdentifier &schema_identifier, TableNameList &set_of_names)
588
CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
590
if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
592
else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
596
if (directory.fail())
598
errno= directory.getError();
600
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
602
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
607
for_each(vector_of_engines.begin(), vector_of_engines.end(),
608
AddTableName(directory, schema_identifier, set_of_names));
610
session.doGetTableNames(directory, schema_identifier, set_of_names);
613
void StorageEngine::getTableIdentifiers(Session &session, SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
615
CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
617
if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
619
else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
623
if (directory.fail())
625
errno= directory.getError();
627
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), schema_identifier.getSQLPath().c_str());
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");
581
CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
583
if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
585
else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
589
if (directory.fail())
591
errno= directory.getError();
593
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), const_cast<SchemaIdentifier &>(schema_identifier).getSQLPath().c_str());
629
595
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
637
603
session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
606
class DropTable: public unary_function<TableIdentifier&, bool>
609
StorageEngine *engine;
613
DropTable(Session &session_arg, StorageEngine *engine_arg) :
614
session(session_arg),
618
result_type operator() (argument_type identifier)
620
return engine->doDropTable(session, identifier) == 0;
640
624
/* This will later be converted to TableIdentifiers */
641
625
class DropTables: public unary_function<StorageEngine *, void>
643
627
Session &session;
644
TableIdentifierList &table_identifiers;
628
TableIdentifiers &table_identifiers;
648
DropTables(Session &session_arg, TableIdentifierList &table_identifiers_arg) :
632
DropTables(Session &session_arg, TableIdentifiers &table_identifiers_arg) :
649
633
session(session_arg),
650
634
table_identifiers(table_identifiers_arg)
653
637
result_type operator() (argument_type engine)
655
for (TableIdentifierList::iterator iter= table_identifiers.begin();
656
iter != table_identifiers.end();
659
int error= engine->doDropTable(session, const_cast<TableIdentifier&>(*iter));
661
// On a return of zero we know we found and deleted the table. So we
662
// remove it from our search.
664
table_identifiers.erase(iter);
639
// True returning from DropTable means the table has been successfully
640
// 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)),
644
table_identifiers.end());
788
767
const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
791
(table->key_info[0].key_part[0].field->flags &
793
&& (current_session)->lex->sql_command == SQLCOM_ALTER_TABLE)
795
err_msg= ER(ER_DUP_ENTRY_AUTOINCREMENT_CASE);
798
769
print_keydup_error(key_nr, err_msg, *table);
801
773
textno=ER_DUP_KEY;
822
794
str.length(max_length-4);
823
795
str.append(STRING_WITH_LEN("..."));
825
my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table->s->table_name.str,
797
my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table->getShare()->getTableName(),
826
798
str.c_ptr(), key_nr+1);
901
873
case HA_ERR_NO_SUCH_TABLE:
903
my_error(ER_NO_SUCH_TABLE, MYF(0), table->s->getSchemaName(),
904
table->s->table_name.str);
875
my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
876
table->getShare()->getTableName());
906
878
case HA_ERR_RBR_LOGGING_FAILED:
907
879
textno= ER_BINLOG_ROW_LOGGING_FAILED;
1013
985
return internal::my_delete(path.c_str(), MYF(0));
1016
int StorageEngine::renameDefinitionFromPath(TableIdentifier &dest, TableIdentifier &src)
988
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1018
990
message::Table table_message;
1019
991
string src_path(src.getPath());
1045
int StorageEngine::writeDefinitionFromPath(TableIdentifier &identifier, message::Table &table_message)
1017
int StorageEngine::writeDefinitionFromPath(const TableIdentifier &identifier, message::Table &table_message)
1047
1019
char definition_file_tmp[FN_REFLEN];
1048
1020
string file_name(identifier.getPath());
1062
1034
google::protobuf::io::ZeroCopyOutputStream* output=
1063
1035
new google::protobuf::io::FileOutputStream(fd);
1065
if (not table_message.SerializeToZeroCopyStream(output))
1040
success= table_message.SerializeToZeroCopyStream(output);
1067
1049
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1068
1050
table_message.InitializationErrorString().c_str());
1107
1089
class CanCreateTable: public unary_function<StorageEngine *, bool>
1109
TableIdentifier &identifier;
1091
const TableIdentifier &identifier;
1112
CanCreateTable(TableIdentifier &identifier_arg) :
1094
CanCreateTable(const TableIdentifier &identifier_arg) :
1113
1095
identifier(identifier_arg)
1124
1106
@note on success table can be created.
1126
bool StorageEngine::canCreateTable(drizzled::TableIdentifier &identifier)
1108
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1128
1110
EngineVector::iterator iter=
1129
1111
find_if(vector_of_engines.begin(), vector_of_engines.end(),
1144
1126
if (input.good())
1146
if (table_message.ParseFromIstream(&input))
1129
if (table_message.ParseFromIstream(&input))
1136
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1137
table_message.InitializationErrorString().empty() ? "": table_message.InitializationErrorString().c_str());
1151
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1152
table_message.InitializationErrorString().c_str());