35
36
#include <drizzled/sql_base.h>
36
37
#include <drizzled/lock.h>
37
38
#include <drizzled/errmsg_print.h>
38
#include <drizzled/transaction_services.h>
39
#include <drizzled/replication_services.h>
39
40
#include <drizzled/message/schema.pb.h>
40
41
#include "drizzled/sql_table.h"
41
#include "drizzled/plugin/storage_engine.h"
42
#include "drizzled/plugin/authorization.h"
42
#include "drizzled/plugin/info_schema_table.h"
43
43
#include "drizzled/global_charset_info.h"
44
44
#include "drizzled/pthread_globals.h"
45
45
#include "drizzled/charset.h"
47
#include <boost/thread/mutex.hpp>
49
boost::mutex LOCK_create_db;
51
47
#include "drizzled/internal/my_sys.h"
50
using namespace drizzled;
52
#define MY_DB_OPT_FILE "db.opt"
53
53
#define MAX_DROP_TABLE_Q_LEN 1024
60
static long drop_tables_via_filenames(Session *session,
61
SchemaIdentifier &schema_identifier,
62
TableIdentifier::vector &dropped_tables);
63
static void mysql_change_db_impl(Session *session);
64
static void mysql_change_db_impl(Session *session, SchemaIdentifier &schema_identifier);
55
const string del_exts[]= {".dfe", ".blk", ".arz", ".BAK", ".TMD", ".opt"};
56
static set<string> deletable_extentions(del_exts, &del_exts[sizeof(del_exts)/sizeof(del_exts[0])]);
59
static long mysql_rm_known_files(Session *session, CachedDirectory &dirp,
60
const string &db, const char *path,
61
TableList **dropped_tables);
64
Return default database collation.
66
@param session Thread context.
67
@param db_name Database name.
69
@return CHARSET_INFO object. The operation always return valid character
70
set, even if the database does not exist.
73
const CHARSET_INFO *get_default_db_collation(const char *db_name)
77
get_database_metadata(db_name, &db);
79
/* If for some reason the db.opt file lacks a collation,
80
we just return the default */
82
if (db.has_collation())
84
const string buffer= db.collation();
85
const CHARSET_INFO* cs= get_charset_by_name(buffer.c_str());
89
errmsg_printf(ERRMSG_LVL_ERROR,
90
_("Error while loading database options: '%s':"),db_name);
91
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
93
return default_charset_info;
99
return default_charset_info;
102
/* path is path to database, not schema file */
103
static int write_schema_file(const DatabasePathName &path, const message::Schema &db)
105
char schema_file_tmp[FN_REFLEN];
106
string schema_file(path.to_string());
108
snprintf(schema_file_tmp, FN_REFLEN, "%s%c%s.tmpXXXXXX", path.to_string().c_str(), FN_LIBCHAR, MY_DB_OPT_FILE);
110
schema_file.append(1, FN_LIBCHAR);
111
schema_file.append(MY_DB_OPT_FILE);
113
int fd= mkstemp(schema_file_tmp);
119
if (!db.SerializeToFileDescriptor(fd))
122
unlink(schema_file_tmp);
126
if (rename(schema_file_tmp, schema_file.c_str()) == -1)
136
int get_database_metadata(const char *dbname, message::Schema *db)
138
char db_opt_path[FN_REFLEN];
142
Pass an empty file name, and the database options file name as extension
143
to avoid table name to file name encoding.
145
length= build_table_filename(db_opt_path, sizeof(db_opt_path),
147
strcpy(db_opt_path + length, MY_DB_OPT_FILE);
149
int fd= open(db_opt_path, O_RDONLY);
154
if (!db->ParseFromFileDescriptor(fd))
101
212
has the global read lock and refuses the operation with
102
213
ER_CANT_UPDATE_WITH_READLOCK if applicable.
104
if (session->wait_if_global_read_lock(false, true))
215
if (wait_if_global_read_lock(session, 0, 1))
109
assert(schema_message.has_name());
110
assert(schema_message.has_collation());
221
pthread_mutex_lock(&LOCK_create_db);
112
// @todo push this lock down into the engine
223
if (mkdir(database_path.to_string().c_str(),0777) == -1)
114
boost::mutex::scoped_lock scopedLock(LOCK_create_db);
116
// Check to see if it exists already.
117
SchemaIdentifier schema_identifier(schema_message.name());
118
if (plugin::StorageEngine::doesSchemaExist(schema_identifier))
120
if (not is_if_not_exists)
122
my_error(ER_DB_CREATE_EXISTS, MYF(0), schema_message.name().c_str());
127
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
128
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
129
schema_message.name().c_str());
227
if (! is_if_not_exists)
229
my_error(ER_DB_CREATE_EXISTS, MYF(0), database_name.to_string().c_str());
233
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
234
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
235
database_name.to_string().c_str());
133
else if (not plugin::StorageEngine::createSchema(schema_message)) // Try to create it
241
my_error(ER_CANT_CREATE_DB, MYF(0), database_name.to_string().c_str(), errno);
246
error_erno= write_schema_file(database_path, *schema_message);
247
if (error_erno && error_erno != EEXIST)
249
if (rmdir(database_path.to_string().c_str()) >= 0)
135
my_error(ER_CANT_CREATE_DB, MYF(0), schema_message.name().c_str(), errno);
140
transaction_services.createSchema(session, schema_message);
144
session->startWaitingGlobalReadLock();
258
replication_services.rawStatement(session, session->query, session->query_length);
259
session->my_ok(result);
262
pthread_mutex_unlock(&LOCK_create_db);
263
start_waiting_global_read_lock(session);
150
269
/* db-name is already validated when we come here */
152
bool mysql_alter_db(Session *session, const message::Schema &schema_message)
271
bool mysql_alter_db(Session *session, const NormalisedDatabaseName &database_name, message::Schema *schema_message)
154
TransactionServices &transaction_services= TransactionServices::singleton();
273
ReplicationServices &replication_services= ReplicationServices::singleton();
276
DatabasePathName database_path(database_name);
157
279
Do not alter database if another thread is holding read lock.
234
358
has the global read lock and refuses the operation with
235
359
ER_CANT_UPDATE_WITH_READLOCK if applicable.
237
if (session->wait_if_global_read_lock(false, true))
361
if (wait_if_global_read_lock(session, 0, 1))
242
// Lets delete the temporary tables first outside of locks.
243
set<string> set_of_names;
244
session->doGetTableNames(schema_identifier, set_of_names);
246
for (set<string>::iterator iter= set_of_names.begin(); iter != set_of_names.end(); iter++)
248
TableIdentifier identifier(schema_identifier, *iter, message::Table::TEMPORARY);
249
Table *table= session->find_temporary_table(identifier);
250
session->close_temporary_table(table);
254
boost::mutex::scoped_lock scopedLock(LOCK_create_db);
256
/* See if the schema exists */
257
if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
260
schema_identifier.getSQLPath(path);
264
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
265
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
271
my_error(ER_DB_DROP_EXISTS, MYF(0), path.c_str());
277
/* After deleting database, remove all cache entries related to schema */
278
table::Cache::singleton().removeSchema(schema_identifier);
366
pthread_mutex_lock(&LOCK_create_db);
368
length= build_table_filename(path, sizeof(path),
369
database_name.to_string().c_str(), "", false);
370
strcpy(path+length, MY_DB_OPT_FILE); // Append db option file name
372
path[length]= '\0'; // Remove file name
374
/* See if the directory exists */
375
CachedDirectory dirp(path);
282
deleted= drop_tables_via_filenames(session, schema_identifier, dropped_tables);
381
my_error(ER_DB_DROP_EXISTS, MYF(0), database_name.to_string().c_str());
385
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
386
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
387
database_name.to_string().c_str());
391
pthread_mutex_lock(&LOCK_open); /* After deleting database, remove all cache entries related to schema */
392
remove_db_from_cache(database_name.to_string().c_str());
393
pthread_mutex_unlock(&LOCK_open);
397
deleted= mysql_rm_known_files(session, dirp,
398
database_name.to_string(),
399
path, &dropped_tables);
288
400
if (deleted >= 0)
290
assert(not session->getQueryString()->empty());
292
TransactionServices &transaction_services= TransactionServices::singleton();
293
transaction_services.dropSchema(session, schema_identifier.getSchemaName());
294
session->clear_error();
295
session->server_status|= SERVER_STATUS_DB_DROPPED;
296
session->my_ok((uint32_t) deleted);
297
session->server_status&= ~SERVER_STATUS_DB_DROPPED;
402
plugin::StorageEngine::dropDatabase(path);
409
uint32_t query_length;
411
assert(session->query);
413
query= session->query;
414
query_length= session->query_length;
416
ReplicationServices &replication_services= ReplicationServices::singleton();
417
replication_services.rawStatement(session, session->getQueryString(), session->getQueryLength());
418
session->clear_error();
419
session->server_status|= SERVER_STATUS_DB_DROPPED;
420
session->my_ok((uint32_t) deleted);
421
session->server_status&= ~SERVER_STATUS_DB_DROPPED;
425
char *query, *query_pos, *query_end, *query_data_start;
429
if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
430
goto exit; /* not much else we can do */
431
query_pos= query_data_start= strcpy(query,"drop table ")+11;
432
query_end= query + MAX_DROP_TABLE_Q_LEN;
433
db_len= database_name.to_string().length();
435
ReplicationServices &replication_services= ReplicationServices::singleton();
436
for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
301
char *query, *query_pos, *query_end, *query_data_start;
303
if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
304
goto exit; /* not much else we can do */
305
query_pos= query_data_start= strcpy(query,"drop table ")+11;
306
query_end= query + MAX_DROP_TABLE_Q_LEN;
308
TransactionServices &transaction_services= TransactionServices::singleton();
309
for (TableIdentifier::vector::iterator it= dropped_tables.begin();
310
it != dropped_tables.end();
313
uint32_t tbl_name_len;
315
/* 3 for the quotes and the comma*/
316
tbl_name_len= (*it).getTableName().length() + 3;
317
if (query_pos + tbl_name_len + 1 >= query_end)
319
/* These DDL methods and logging protected with LOCK_create_db */
320
transaction_services.rawStatement(session, query);
321
query_pos= query_data_start;
325
query_pos= strcpy(query_pos, (*it).getTableName().c_str()) + (tbl_name_len-3);
330
if (query_pos != query_data_start)
438
uint32_t tbl_name_len;
440
/* 3 for the quotes and the comma*/
441
tbl_name_len= strlen(tbl->table_name) + 3;
442
if (query_pos + tbl_name_len + 1 >= query_end)
332
444
/* These DDL methods and logging protected with LOCK_create_db */
333
transaction_services.rawStatement(session, query);
445
replication_services.rawStatement(session, query, (size_t) (query_pos -1 - query));
446
query_pos= query_data_start;
450
query_pos= strcpy(query_pos,tbl->table_name) + (tbl_name_len-3);
455
if (query_pos != query_data_start)
457
/* These DDL methods and logging protected with LOCK_create_db */
458
replication_services.rawStatement(session, query, (size_t) (query_pos -1 - query));
339
If this database was the client's selected database, we silently
340
change the client's selected database to nothing (to have an empty
341
SELECT DATABASE() in the future). For this we free() session->db and set
344
if (schema_identifier.compare(*session->schema()))
345
mysql_change_db_impl(session);
348
session->startWaitingGlobalReadLock();
464
If this database was the client's selected database, we silently
465
change the client's selected database to nothing (to have an empty
466
SELECT DATABASE() in the future). For this we free() session->db and set
469
if (! session->db.empty() && session->db.compare(database_name.to_string()) == 0)
471
pthread_mutex_unlock(&LOCK_create_db);
472
start_waiting_global_read_lock(session);
354
477
static int rm_table_part2(Session *session, TableList *tables)
356
TransactionServices &transaction_services= TransactionServices::singleton();
358
479
TableList *table;
359
480
String wrong_tables;
361
482
bool foreign_key_error= false;
364
table::Cache::singleton().mutex().lock(); /* Part 2 of rm a table */
366
if (session->lock_table_names_exclusively(tables))
368
table::Cache::singleton().mutex().unlock();
372
/* Don't give warnings for not found errors, as we already generate notes */
373
session->no_warnings_for_error= 1;
375
for (table= tables; table; table= table->next_local)
377
const char *db=table->getSchemaName();
378
TableIdentifier identifier(table->getSchemaName(), table->getTableName());
380
plugin::StorageEngine *table_type;
382
error= session->drop_temporary_table(identifier);
386
// removed temporary table
390
tables->unlock_table_names();
391
table::Cache::singleton().mutex().unlock();
392
session->no_warnings_for_error= 0;
396
// temporary table not found
400
table_type= table->getDbType();
404
abort_locked_tables(session, identifier);
405
table::Cache::singleton().removeTable(session, identifier,
406
RTFC_WAIT_OTHER_THREAD_FLAG |
407
RTFC_CHECK_KILLED_FLAG);
409
If the table was used in lock tables, remember it so that
410
unlock_table_names can free it
412
if ((locked_table= drop_locked_tables(session, identifier)))
413
table->table= locked_table;
415
if (session->getKilled())
418
tables->unlock_table_names();
419
table::Cache::singleton().mutex().unlock();
420
session->no_warnings_for_error= 0;
425
identifier.getPath();
427
if (table_type == NULL && not plugin::StorageEngine::doesTableExist(*session, identifier))
429
// Table was not found on disk and table can't be created from engine
430
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
431
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
432
table->getTableName());
436
error= plugin::StorageEngine::dropTable(*session, identifier);
438
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
441
session->clear_error();
444
if (error == HA_ERR_ROW_IS_REFERENCED)
446
/* the table is referenced by a foreign key constraint */
447
foreign_key_error= true;
451
if (error == 0 || (foreign_key_error == false))
453
transaction_services.dropTable(session, string(db), string(table->getTableName()), true);
458
if (wrong_tables.length())
459
wrong_tables.append(',');
460
wrong_tables.append(String(table->getTableName(),system_charset_info));
464
It's safe to unlock table::Cache::singleton().mutex(): we have an exclusive lock
467
table::Cache::singleton().mutex().unlock();
484
pthread_mutex_lock(&LOCK_open); /* Part 2 of rm a table */
487
If we have the table in the definition cache, we don't have to check the
488
.frm cursor to find if the table is a normal table (not view) and what
492
for (table= tables; table; table= table->next_local)
495
table->db_type= NULL;
496
if ((share= TableShare::getShare(table->db, table->table_name)))
497
table->db_type= share->db_type();
500
if (lock_table_names_exclusively(session, tables))
502
pthread_mutex_unlock(&LOCK_open);
506
/* Don't give warnings for not found errors, as we already generate notes */
507
session->no_warnings_for_error= 1;
509
for (table= tables; table; table= table->next_local)
512
plugin::StorageEngine *table_type;
514
error= session->drop_temporary_table(table);
518
// removed temporary table
522
goto err_with_placeholders;
524
// temporary table not found
528
table_type= table->db_type;
532
abort_locked_tables(session, db, table->table_name);
533
remove_table_from_cache(session, db, table->table_name,
534
RTFC_WAIT_OTHER_THREAD_FLAG |
535
RTFC_CHECK_KILLED_FLAG);
537
If the table was used in lock tables, remember it so that
538
unlock_table_names can free it
540
if ((locked_table= drop_locked_tables(session, db, table->table_name)))
541
table->table= locked_table;
546
goto err_with_placeholders;
550
TableIdentifier identifier(db, table->table_name, table->internal_tmp_table ? INTERNAL_TMP_TABLE : NO_TMP_TABLE);
552
if ((table_type == NULL
553
&& (plugin::StorageEngine::getTableDefinition(*session,
554
identifier) != EEXIST)))
556
// Table was not found on disk and table can't be created from engine
557
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
558
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
563
error= plugin::StorageEngine::dropTable(*session,
567
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
570
session->clear_error();
573
if (error == HA_ERR_ROW_IS_REFERENCED)
575
/* the table is referenced by a foreign key constraint */
576
foreign_key_error= true;
580
if (error == 0 || (foreign_key_error == false))
581
write_bin_log_drop_table(session, true, db, table->table_name);
585
if (wrong_tables.length())
586
wrong_tables.append(',');
587
wrong_tables.append(String(table->table_name,system_charset_info));
591
It's safe to unlock LOCK_open: we have an exclusive lock
594
pthread_mutex_unlock(&LOCK_open);
471
596
if (wrong_tables.length())
473
if (not foreign_key_error)
598
if (!foreign_key_error)
474
599
my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
475
600
wrong_tables.c_ptr());
494
619
session MUST be set when calling this function!
497
static long drop_tables_via_filenames(Session *session,
498
SchemaIdentifier &schema_identifier,
499
TableIdentifier::vector &dropped_tables)
622
static long mysql_rm_known_files(Session *session, CachedDirectory &dirp,
624
const char *org_path,
625
TableList **dropped_tables)
630
char filePath[FN_REFLEN];
502
631
TableList *tot_list= NULL, **tot_list_next;
504
633
tot_list_next= &tot_list;
506
plugin::StorageEngine::getIdentifiers(*session, schema_identifier, dropped_tables);
508
for (TableIdentifier::vector::iterator it= dropped_tables.begin();
509
it != dropped_tables.end();
635
for (CachedDirectory::Entries::const_iterator iter= dirp.getEntries().begin();
636
iter != dirp.getEntries().end() && !session->killed;
512
size_t db_len= schema_identifier.getSchemaName().size();
514
/* Drop the table nicely */
515
TableList *table_list=(TableList*)
516
session->calloc(sizeof(*table_list) +
518
(*it).getTableName().length() + 1);
523
table_list->setSchemaName((char*) (table_list+1));
524
table_list->setTableName(strcpy((char*) (table_list+1), schema_identifier.getSchemaName().c_str()) + db_len + 1);
525
TableIdentifier::filename_to_tablename((*it).getTableName().c_str(), const_cast<char *>(table_list->getTableName()), (*it).getTableName().size() + 1);
526
table_list->alias= table_list->getTableName(); // If lower_case_table_names=2
527
table_list->setInternalTmpTable((strncmp((*it).getTableName().c_str(),
529
strlen(TMP_FILE_PREFIX)) == 0));
531
(*tot_list_next)= table_list;
532
tot_list_next= &table_list->next_local;
639
string filename((*iter)->filename);
641
/* skiping . and .. */
642
if (filename[0] == '.' && (!filename[1] ||
643
(filename[1] == '.' && !filename[2])))
646
string extension("");
647
size_t ext_pos= filename.rfind('.');
648
if (ext_pos != string::npos)
650
extension= filename.substr(ext_pos);
652
if (deletable_extentions.find(extension) == deletable_extentions.end())
657
strange checking for magic extensions that are then deleted if
658
not reg_ext (i.e. .frm).
660
and (previously) we'd err out on drop database if files not matching
661
engine ha_known_exts() or deletable_extensions were present.
663
presumably this was to avoid deleting other user data... except if that
664
data happened to be in files ending in .BAK, .opt or .TMD. *fun*
668
/* just for safety we use files_charset_info */
669
if (!my_strcasecmp(files_charset_info, extension.c_str(), ".dfe"))
671
size_t db_len= db.size();
673
/* Drop the table nicely */
674
filename.erase(ext_pos);
675
TableList *table_list=(TableList*)
676
session->calloc(sizeof(*table_list) +
678
filename.size() + 1);
682
table_list->db= (char*) (table_list+1);
683
table_list->table_name= strcpy(table_list->db, db.c_str()) + db_len + 1;
684
filename_to_tablename(filename.c_str(), table_list->table_name,
685
filename.size() + 1);
686
table_list->alias= table_list->table_name; // If lower_case_table_names=2
687
table_list->internal_tmp_table= (strncmp(filename.c_str(),
689
strlen(TMP_FILE_PREFIX)) == 0);
691
(*tot_list_next)= table_list;
692
tot_list_next= &table_list->next_local;
697
sprintf(filePath, "%s/%s", org_path, filename.c_str());
698
if (my_delete_with_symlink(filePath,MYF(MY_WME)))
535
if (session->getKilled())
616
784
@retval true Error
619
bool mysql_change_db(Session *session, SchemaIdentifier &schema_identifier)
787
bool mysql_change_db(Session *session, const NormalisedDatabaseName &normalised_database_name, bool force_switch)
622
if (not plugin::Authorization::isAuthorized(session->getSecurityContext(), schema_identifier))
624
/* Error message is set in isAuthorized */
628
if (not check_db_name(session, schema_identifier))
631
schema_identifier.getSQLPath(path);
632
my_error(ER_WRONG_DB_NAME, MYF(0), path.c_str());
637
if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
639
/* Report an error and free new_db_file_name. */
641
schema_identifier.getSQLPath(path);
643
my_error(ER_BAD_DB_ERROR, MYF(0), path.c_str());
645
/* The operation failed. */
650
mysql_change_db_impl(session, schema_identifier);
789
const CHARSET_INFO *db_default_cl;
791
if (my_strcasecmp(system_charset_info, normalised_database_name.to_string().c_str(),
792
INFORMATION_SCHEMA_NAME.c_str()) == 0)
794
NonNormalisedDatabaseName non_normalised_i_s(INFORMATION_SCHEMA_NAME);
795
NormalisedDatabaseName is_name(non_normalised_i_s);
797
session->set_db(is_name);
802
NOTE: if check_db_name() fails, we should throw an error in any case,
803
even if we are called from sp_head::execute().
805
It's next to impossible however to get this error when we are called
806
from sp_head::execute(). But let's switch the current database to NULL
807
in this case to be sure.
809
if (! normalised_database_name.isValid())
811
my_error(ER_WRONG_DB_NAME, MYF(0),
812
normalised_database_name.to_string().c_str());
820
DatabasePathName database_path(normalised_database_name);
822
if (! database_path.exists())
826
/* Throw a warning and free new_db_file_name. */
828
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
829
ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
830
normalised_database_name.to_string().c_str());
832
/* Change db to NULL. */
836
/* The operation succeed. */
842
/* Report an error and free new_db_file_name. */
844
my_error(ER_BAD_DB_ERROR, MYF(0),
845
normalised_database_name.to_string().c_str());
847
/* The operation failed. */
853
db_default_cl= get_default_db_collation(normalised_database_name.to_string().c_str());
855
session->set_db(normalised_database_name);
656
@brief Internal implementation: switch current database to a valid one.
658
@param session Thread context.
659
@param new_db_name Name of the database to switch to. The function will
660
take ownership of the name (the caller must not free
661
the allocated memory). If the name is NULL, we're
662
going to switch to NULL db.
663
@param new_db_charset Character set of the new database.
666
static void mysql_change_db_impl(Session *session, SchemaIdentifier &schema_identifier)
668
/* 1. Change current database in Session. */
671
if (new_db_name == NULL)
674
Session::set_db() does all the job -- it frees previous database name and
678
session->set_db(NULL, 0);
684
Here we already have a copy of database name to be used in Session. So,
685
we just call Session::reset_db(). Since Session::reset_db() does not releases
686
the previous database name, we should do it explicitly.
689
session->set_db(schema_identifier.getSchemaName());
693
static void mysql_change_db_impl(Session *session)
695
session->set_db(string());
698
} /* namespace drizzled */
860
NormalisedDatabaseName::NormalisedDatabaseName(const NonNormalisedDatabaseName &dbname)
862
const std::string &non_norm_string= dbname.to_string();
863
database_name= (char*)malloc(non_norm_string.size()+1);
865
assert(database_name); /* FIXME: should throw exception */
867
strncpy(database_name, non_norm_string.c_str(), non_norm_string.size()+1);
869
my_casedn_str(files_charset_info, database_name);
872
NormalisedDatabaseName::~NormalisedDatabaseName()
877
bool NormalisedDatabaseName::isValid() const
879
LEX_STRING db_lexstring;
881
db_lexstring.str= database_name;
882
db_lexstring.length= strlen(database_name);
884
if (db_lexstring.length == 0
885
|| db_lexstring.length > NAME_LEN
886
|| database_name[db_lexstring.length - 1] == ' ')
889
return (! check_identifier_name(&db_lexstring));
892
DatabasePathName::DatabasePathName(const NormalisedDatabaseName &database_name)
894
char db_dir_path[FN_REFLEN];
895
uint32_t db_dir_path_len;
897
db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path),
898
database_name.to_string().c_str(),
901
if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
902
db_dir_path[db_dir_path_len - 1]= 0;
904
database_path.assign(db_dir_path);
907
bool DatabasePathName::exists() const
909
/* TODO: handle EIO and other fun errors */
910
return access(database_path.c_str(), F_OK) == 0;