107
105
hash_delete(&lock_db_cache, (unsigned char*) opt);
109
/* Database options hash */
110
static HASH dboptions;
111
static bool dboptions_init= 0;
112
static pthread_rwlock_t LOCK_dboptions;
114
/* Structure for database options */
115
typedef struct my_dbopt_st
117
char *name; /* Database name */
118
uint32_t name_length; /* Database length name */
119
const CHARSET_INFO *charset; /* Database default character set */
124
Function we use in the creation of our hash to get key.
127
extern "C" unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
130
unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
131
bool not_used __attribute__((unused)))
133
*length= opt->name_length;
134
return (unsigned char*) opt->name;
111
139
Helper function to write a query to binlog used by mysql_rm_db()
114
static inline void write_to_binlog(Session *session, char *query, uint32_t query_length, char *, uint32_t)
116
(void)replicator_statement(session, query, query_length);
142
static inline void write_to_binlog(Session *session, char *query, uint32_t q_len,
143
char *db, uint32_t db_len)
145
Query_log_event qinfo(session, query, q_len, 0, 0);
148
qinfo.db_len= db_len;
149
drizzle_bin_log.write(&qinfo);
154
Function to free dboptions hash element
157
extern "C" void free_dbopt(void *dbopt);
159
void free_dbopt(void *dbopt)
161
free((unsigned char*) dbopt);
120
166
Initialize database option hash and locked database hash.
149
Return default database collation.
151
@param session Thread context.
152
@param db_name Database name.
154
@return CHARSET_INFO object. The operation always return valid character
155
set, even if the database does not exist.
158
const CHARSET_INFO *get_default_db_collation(Session *session, const char *db_name)
160
HA_CREATE_INFO db_info;
162
if (session->db != NULL && strcmp(db_name, session->db) == 0)
163
return session->db_charset;
166
db_info.default_table_charset contains valid character set
170
load_db_opt_by_name(session, db_name, &db_info);
172
return db_info.default_table_charset;
175
/* path is path to database, not schema file */
176
static int write_schema_file(Session *session,
177
const char *path, const char *name,
178
HA_CREATE_INFO *create)
202
Free database option hash and locked databases hash.
205
void my_database_names_free(void)
210
hash_free(&dboptions);
211
(void) pthread_rwlock_destroy(&LOCK_dboptions);
212
hash_free(&lock_db_cache);
218
Cleanup cached options
221
void my_dbopt_cleanup(void)
223
pthread_rwlock_wrlock(&LOCK_dboptions);
224
hash_free(&dboptions);
225
hash_init(&dboptions, lower_case_table_names ?
226
&my_charset_bin : system_charset_info,
227
32, 0, 0, (hash_get_key) dboptions_get_key,
229
pthread_rwlock_unlock(&LOCK_dboptions);
234
Find database options in the hash.
237
Search a database options in the hash, usings its path.
238
Fills "create" on success.
245
static bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
251
length= (uint) strlen(dbname);
253
pthread_rwlock_rdlock(&LOCK_dboptions);
254
if ((opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
256
create->default_table_charset= opt->charset;
259
pthread_rwlock_unlock(&LOCK_dboptions);
265
Writes database options into the hash.
268
Inserts database options into the hash, or updates
269
options if they are already in the hash.
276
static bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
282
length= (uint) strlen(dbname);
284
pthread_rwlock_wrlock(&LOCK_dboptions);
285
if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
287
/* Options are not in the hash, insert them */
289
if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
290
&opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
298
strcpy(opt->name, dbname);
299
opt->name_length= length;
301
if ((error= my_hash_insert(&dboptions, (unsigned char*) opt)))
308
/* Update / write options in hash */
309
opt->charset= create->default_table_charset;
312
pthread_rwlock_unlock(&LOCK_dboptions);
318
Deletes database options from the hash.
321
void del_dbopt(const char *path)
324
pthread_rwlock_wrlock(&LOCK_dboptions);
325
if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const unsigned char*) path,
327
hash_delete(&dboptions, (unsigned char*) opt);
328
pthread_rwlock_unlock(&LOCK_dboptions);
333
Create database options file:
336
Currently database default charset is only stored there.
340
1 Could not create file or write to it. Error sent through my_error()
343
static bool write_db_opt(Session *session, const char *path, const char *name, HA_CREATE_INFO *create)
180
346
drizzle::Schema db;
181
char schema_file_tmp[FN_REFLEN];
182
string schema_file(path);
188
snprintf(schema_file_tmp, FN_REFLEN, "%s%c%s.tmpXXXXXX", path, FN_LIBCHAR, MY_DB_OPT_FILE);
190
schema_file.append(1, FN_LIBCHAR);
191
schema_file.append(MY_DB_OPT_FILE);
193
int fd= mkstemp(schema_file_tmp);
198
350
if (!create->default_table_charset)
199
351
create->default_table_charset= session->variables.collation_server;
353
if (put_dbopt(path, create))
201
356
db.set_name(name);
357
db.set_characterset(create->default_table_charset->csname);
202
358
db.set_collation(create->default_table_charset->name);
204
if (!db.SerializeToFileDescriptor(fd))
207
unlink(schema_file_tmp);
211
if (rename(schema_file_tmp, schema_file.c_str()) == -1)
360
fstream output(path, ios::out | ios::trunc | ios::binary);
361
if (!db.SerializeToOstream(&output))
221
int load_db_opt(Session *session, const char *path, HA_CREATE_INFO *create)
369
Load database options file
372
path Path for option file
373
create Where to store the read options
379
1 No database file or could not open it
383
bool load_db_opt(Session *session, const char *path, HA_CREATE_INFO *create)
223
386
drizzle::Schema db;
226
389
memset(create, 0, sizeof(*create));
227
390
create->default_table_charset= session->variables.collation_server;
229
int fd= open(path, O_RDONLY);
234
if (!db.ParseFromFileDescriptor(fd))
392
/* Check if options for this database are already in the hash */
393
if (!get_dbopt(path, create))
396
fstream input(path, ios::in | ios::binary);
399
else if (!db.ParseFromIstream(&input))
402
buffer= db.characterset();
403
if (!(create->default_table_charset= get_charset_by_csname(buffer.c_str(), MY_CS_PRIMARY, MYF(0))))
405
errmsg_printf(ERRMSG_LVL_ERROR, _("Error while loading database options: '%s':"),path);
406
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
407
create->default_table_charset= default_charset_info;
241
410
buffer= db.collation();
242
if (!(create->default_table_charset= get_charset_by_name(buffer.c_str())))
411
if (!(create->default_table_charset= get_charset_by_name(buffer.c_str(), MYF(0))))
244
errmsg_printf(ERRMSG_LVL_ERROR,
245
_("Error while loading database options: '%s':"),path);
413
errmsg_printf(ERRMSG_LVL_ERROR, _("Error while loading database options: '%s':"),path);
246
414
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
247
415
create->default_table_charset= default_charset_info;
419
Put the loaded value into the hash.
420
Note that another thread could've added the same
421
entry to the hash after we called get_dbopt(),
422
but it's not an error, as put_dbopt() takes this
423
possibility into account.
425
error= put_dbopt(path, create);
254
int load_db_opt_by_name(Session *session, const char *db_name,
255
HA_CREATE_INFO *db_create_info)
433
Retrieve database options by name. Load database options file or fetch from
437
load_db_opt_by_name()
438
db_name Database name
439
db_create_info Where to store the database options
442
load_db_opt_by_name() is a shortcut for load_db_opt().
445
Although load_db_opt_by_name() (and load_db_opt()) returns status of
446
the operation, it is useless usually and should be ignored. The problem
447
is that there are 1) system databases ("mysql") and 2) virtual
448
databases ("information_schema"), which do not contain options file.
449
So, load_db_opt[_by_name]() returns false for these databases, but this
452
load_db_opt[_by_name]() clears db_create_info structure in any case, so
453
even on failure it contains valid data. So, common use case is just
454
call load_db_opt[_by_name]() without checking return value and use
455
db_create_info right after that.
457
RETURN VALUES (read NOTE!)
459
true Failed to retrieve options
462
bool load_db_opt_by_name(Session *session, const char *db_name,
463
HA_CREATE_INFO *db_create_info)
257
465
char db_opt_path[FN_REFLEN];
328
pthread_mutex_lock(&LOCK_drizzleclient_create_db);
568
pthread_mutex_lock(&LOCK_drizzle_create_db);
330
570
/* Check directory */
331
571
path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
332
572
path[path_len-1]= 0; // Remove last '/' from path
334
if (mkdir(path,0777) == -1)
574
if (!stat(path,&stat_info))
576
if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
338
if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
340
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
344
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
345
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
578
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
352
my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
582
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
583
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
593
my_error(EE_STAT, MYF(0), path, errno);
596
if (mkdir(path,0777) < 0)
598
my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
357
error= write_schema_file(session, path, db, create_info);
358
if (error && error != EEXIST)
604
path[path_len-1]= FN_LIBCHAR;
605
strncpy(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
606
if (write_db_opt(session, path, db, create_info))
609
Could not create options file.
610
Restore things to beginning.
360
613
if (rmdir(path) >= 0)
619
We come here when we managed to create the database, but not the option
620
file. In this case it's best to just continue as if nothing has
621
happened. (This is a very unlikely senario)
397
682
bool mysql_alter_db(Session *session, const char *db, HA_CREATE_INFO *create_info)
684
char path[FN_REFLEN+16];
401
char path[FN_REFLEN+16];
405
689
Do not alter database if another thread is holding read lock.
406
Wait for global read lock before acquiring LOCK_drizzleclient_create_db.
690
Wait for global read lock before acquiring LOCK_drizzle_create_db.
407
691
After wait_if_global_read_lock() we have protection against another
408
global read lock. If we would acquire LOCK_drizzleclient_create_db first,
692
global read lock. If we would acquire LOCK_drizzle_create_db first,
409
693
another thread could step in and get the global read lock before we
410
694
reach wait_if_global_read_lock(). If this thread tries the same as we
411
(admin a db), it would then go and wait on LOCK_drizzleclient_create_db...
695
(admin a db), it would then go and wait on LOCK_drizzle_create_db...
412
696
Furthermore wait_if_global_read_lock() checks if the current thread
413
697
has the global read lock and refuses the operation with
414
698
ER_CANT_UPDATE_WITH_READLOCK if applicable.
416
700
if ((error=wait_if_global_read_lock(session,0,1)))
703
pthread_mutex_lock(&LOCK_drizzle_create_db);
706
Recreate db options file: /dbpath/.db.opt
707
We pass MY_DB_OPT_FILE as "extension" to avoid
708
"table name to file name" encoding.
710
build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0);
711
if ((error=write_db_opt(session, path, db, create_info)))
419
pthread_mutex_lock(&LOCK_drizzleclient_create_db);
421
714
/* Change options if current database is being altered. */
422
path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
423
path[path_len-1]= 0; // Remove last '/' from path
425
error= write_schema_file(session, path, db, create_info);
426
if (error && error != EEXIST)
428
/* TODO: find some witty way of getting back an error message */
429
pthread_mutex_unlock(&LOCK_drizzleclient_create_db);
433
716
if (session->db && !strcmp(session->db,db))