102
103
/* path is path to database, not schema file */
103
static int write_schema_file(const DatabasePathName &path, const message::Schema &db)
104
static int write_schema_file(const char *path, const message::Schema &db)
105
106
char schema_file_tmp[FN_REFLEN];
106
string schema_file(path.to_string());
107
string schema_file(path);
108
snprintf(schema_file_tmp, FN_REFLEN, "%s%c%s.tmpXXXXXX", path.to_string().c_str(), FN_LIBCHAR, MY_DB_OPT_FILE);
109
snprintf(schema_file_tmp, FN_REFLEN, "%s%c%s.tmpXXXXXX", path, FN_LIBCHAR, MY_DB_OPT_FILE);
110
111
schema_file.append(1, FN_LIBCHAR);
111
112
schema_file.append(MY_DB_OPT_FILE);
185
bool mysql_create_db(Session *session, const NormalisedDatabaseName &database_name, message::Schema *schema_message, bool is_if_not_exists)
186
bool mysql_create_db(Session *session, const char *db, drizzled::message::Schema *schema_message, bool is_if_not_exists)
187
188
ReplicationServices &replication_services= ReplicationServices::singleton();
190
191
bool error= false;
191
DatabasePathName database_path(database_name);
193
193
/* do not create 'information_schema' db */
194
if (!my_strcasecmp(system_charset_info, database_name.to_string().c_str(), INFORMATION_SCHEMA_NAME.c_str()))
194
if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.c_str()))
196
my_error(ER_DB_CREATE_EXISTS, MYF(0), database_name.to_string().c_str());
196
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
200
assert(database_name.isValid());
201
schema_message->set_name(database_name.to_string());
200
schema_message->set_name(db);
204
203
Do not create database if another thread is holding read lock.
221
220
pthread_mutex_lock(&LOCK_create_db);
223
if (mkdir(database_path.to_string().c_str(),0777) == -1)
222
/* check directory */
223
char path[FN_REFLEN+16];
225
path_len= build_table_filename(path, sizeof(path), db, "", false);
226
path[path_len-1]= 0; // remove last '/' from path
228
if (mkdir(path, 0777) == -1)
225
230
if (errno == EEXIST)
227
232
if (! is_if_not_exists)
229
my_error(ER_DB_CREATE_EXISTS, MYF(0), database_name.to_string().c_str());
234
my_error(ER_DB_CREATE_EXISTS, MYF(0), path);
233
238
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
234
239
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
235
database_name.to_string().c_str());
236
241
session->my_ok();
241
my_error(ER_CANT_CREATE_DB, MYF(0), database_name.to_string().c_str(), errno);
246
my_error(ER_CANT_CREATE_DB, MYF(0), path, errno);
246
error_erno= write_schema_file(database_path, *schema_message);
251
error_erno= write_schema_file(path, *schema_message);
247
252
if (error_erno && error_erno != EEXIST)
249
if (rmdir(database_path.to_string().c_str()) >= 0)
254
if (rmdir(path) >= 0)
269
274
/* db-name is already validated when we come here */
271
bool mysql_alter_db(Session *session, const NormalisedDatabaseName &database_name, message::Schema *schema_message)
276
bool mysql_alter_db(Session *session, const char *db, message::Schema *schema_message)
273
278
ReplicationServices &replication_services= ReplicationServices::singleton();
276
DatabasePathName database_path(database_name);
281
char path[FN_REFLEN+16];
279
285
Do not alter database if another thread is holding read lock.
293
299
assert(schema_message);
294
assert(database_name.isValid());
296
schema_message->set_name(database_name.to_string());
301
schema_message->set_name(db);
298
303
pthread_mutex_lock(&LOCK_create_db);
300
error= write_schema_file(database_path, *schema_message);
305
/* Change options if current database is being altered. */
306
path_len= build_table_filename(path, sizeof(path), db, "", false);
307
path[path_len-1]= 0; // Remove last '/' from path
309
error= write_schema_file(path, *schema_message);
301
310
if (error && error != EEXIST)
303
312
/* TODO: find some witty way of getting back an error message */
341
350
TableList *dropped_tables= NULL;
343
if (database_name.to_string().compare(INFORMATION_SCHEMA_NAME) == 0)
352
if (db && (strcmp(db, "information_schema") == 0))
345
354
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
350
360
Do not drop database if another thread is holding read lock.
351
361
Wait for global read lock before acquiring LOCK_create_db.
381
my_error(ER_DB_DROP_EXISTS, MYF(0), database_name.to_string().c_str());
391
my_error(ER_DB_DROP_EXISTS, MYF(0), path);
385
395
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
386
396
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
387
database_name.to_string().c_str());
391
401
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());
402
remove_db_from_cache(db);
393
403
pthread_mutex_unlock(&LOCK_open);
397
deleted= mysql_rm_known_files(session, dirp,
398
database_name.to_string(),
407
deleted= mysql_rm_known_files(session, dirp, db,
399
408
path, &dropped_tables);
400
409
if (deleted >= 0)
784
793
@retval true Error
787
bool mysql_change_db(Session *session, const NormalisedDatabaseName &normalised_database_name, bool force_switch)
796
bool mysql_change_db(Session *session, const LEX_STRING *new_db_name, bool force_switch)
798
LEX_STRING new_db_file_name;
789
799
const CHARSET_INFO *db_default_cl;
791
if (my_strcasecmp(system_charset_info, normalised_database_name.to_string().c_str(),
802
assert(new_db_name->length);
804
if (my_strcasecmp(system_charset_info, new_db_name->str,
792
805
INFORMATION_SCHEMA_NAME.c_str()) == 0)
794
NonNormalisedDatabaseName non_normalised_i_s(INFORMATION_SCHEMA_NAME);
795
NormalisedDatabaseName is_name(non_normalised_i_s);
807
/* Switch the current database to INFORMATION_SCHEMA. */
808
/* const_cast<> is safe here: mysql_change_db_impl does a copy */
809
LEX_STRING is_name= { const_cast<char *>(INFORMATION_SCHEMA_NAME.c_str()),
810
INFORMATION_SCHEMA_NAME.length() };
811
mysql_change_db_impl(session, &is_name);
797
session->set_db(is_name);
817
Now we need to make a copy because check_db_name requires a
818
non-constant argument. Actually, it takes database file name.
820
TODO: fix check_db_name().
823
new_db_file_name.length= new_db_name->length;
824
new_db_file_name.str= (char *)malloc(new_db_name->length + 1);
825
if (new_db_file_name.str == NULL)
826
return true; /* the error is set */
827
memcpy(new_db_file_name.str, new_db_name->str, new_db_name->length);
828
new_db_file_name.str[new_db_name->length]= 0;
802
832
NOTE: if check_db_name() fails, we should throw an error in any case,
803
833
even if we are called from sp_head::execute().
806
836
from sp_head::execute(). But let's switch the current database to NULL
807
837
in this case to be sure.
809
if (! normalised_database_name.isValid())
840
if (check_db_name(&new_db_file_name))
811
my_error(ER_WRONG_DB_NAME, MYF(0),
812
normalised_database_name.to_string().c_str());
842
my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
843
free(new_db_file_name.str);
814
845
if (force_switch)
846
mysql_change_db_impl(session, NULL);
820
DatabasePathName database_path(normalised_database_name);
822
if (! database_path.exists())
851
if (check_db_dir_existence(new_db_file_name.str))
824
853
if (force_switch)
853
db_default_cl= get_default_db_collation(normalised_database_name.to_string().c_str());
884
db_default_cl= get_default_db_collation(new_db_file_name.str);
855
session->set_db(normalised_database_name);
886
mysql_change_db_impl(session, &new_db_file_name);
887
free(new_db_file_name.str);
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)
893
Check if there is directory for the database name.
896
check_db_dir_existence()
897
db_name database name
900
false There is directory for the specified database name.
901
true The directory does not exist.
904
bool check_db_dir_existence(const char *db_name)
894
906
char db_dir_path[FN_REFLEN];
895
907
uint32_t db_dir_path_len;
897
909
db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path),
898
database_name.to_string().c_str(),
901
912
if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
902
913
db_dir_path[db_dir_path_len - 1]= 0;
904
database_path.assign(db_dir_path);
917
return access(db_dir_path, F_OK);
907
bool DatabasePathName::exists() const
921
@brief Internal implementation: switch current database to a valid one.
923
@param session Thread context.
924
@param new_db_name Name of the database to switch to. The function will
925
take ownership of the name (the caller must not free
926
the allocated memory). If the name is NULL, we're
927
going to switch to NULL db.
928
@param new_db_charset Character set of the new database.
931
static void mysql_change_db_impl(Session *session, LEX_STRING *new_db_name)
909
/* TODO: handle EIO and other fun errors */
910
return access(database_path.c_str(), F_OK) == 0;
933
/* 1. Change current database in Session. */
935
if (new_db_name == NULL)
938
Session::set_db() does all the job -- it frees previous database name and
942
session->set_db(NULL, 0);
947
Here we already have a copy of database name to be used in Session. So,
948
we just call Session::reset_db(). Since Session::reset_db() does not releases
949
the previous database name, we should do it explicitly.
952
session->set_db(new_db_name->str, new_db_name->length);