28
#include <drizzled/error.h>
28
#include <drizzled/message/schema.pb.h>
29
#include "drizzled/error.h"
29
30
#include <drizzled/gettext.h>
30
31
#include <drizzled/my_hash.h>
31
#include <drizzled/internal/m_string.h>
32
#include "drizzled/internal/m_string.h"
32
33
#include <drizzled/session.h>
33
#include <drizzled/schema.h>
34
#include <drizzled/db.h>
34
35
#include <drizzled/sql_base.h>
35
36
#include <drizzled/lock.h>
36
37
#include <drizzled/errmsg_print.h>
37
38
#include <drizzled/transaction_services.h>
38
39
#include <drizzled/message/schema.pb.h>
39
#include <drizzled/sql_table.h>
40
#include <drizzled/plugin/storage_engine.h>
41
#include <drizzled/plugin/authorization.h>
42
#include <drizzled/global_charset_info.h>
43
#include <drizzled/pthread_globals.h>
44
#include <drizzled/charset.h>
45
#include <drizzled/internal/my_sys.h>
40
#include "drizzled/sql_table.h"
41
#include "drizzled/plugin/storage_engine.h"
42
#include "drizzled/plugin/authorization.h"
43
#include "drizzled/global_charset_info.h"
44
#include "drizzled/pthread_globals.h"
45
#include "drizzled/charset.h"
47
47
#include <boost/thread/mutex.hpp>
49
boost::mutex LOCK_create_db;
51
#include "drizzled/internal/my_sys.h"
49
53
#define MAX_DROP_TABLE_Q_LEN 1024
51
55
using namespace std;
59
static void change_db_impl(Session &session);
60
static void change_db_impl(Session &session, identifier::Schema &schema_identifier);
60
static void change_db_impl(Session *session);
61
static void change_db_impl(Session *session, SchemaIdentifier &schema_identifier);
83
bool create(Session &session, const message::Schema &schema_message, const bool is_if_not_exists)
84
bool create_db(Session *session, const message::Schema &schema_message, const bool is_if_not_exists)
85
86
TransactionServices &transaction_services= TransactionServices::singleton();
89
90
Do not create database if another thread is holding read lock.
90
Wait for global read lock before acquiring session->catalog()->schemaLock().
91
Wait for global read lock before acquiring LOCK_create_db.
91
92
After wait_if_global_read_lock() we have protection against another
92
global read lock. If we would acquire session->catalog()->schemaLock() first,
93
global read lock. If we would acquire LOCK_create_db first,
93
94
another thread could step in and get the global read lock before we
94
95
reach wait_if_global_read_lock(). If this thread tries the same as we
95
(admin a db), it would then go and wait on session->catalog()->schemaLock()...
96
(admin a db), it would then go and wait on LOCK_create_db...
96
97
Furthermore wait_if_global_read_lock() checks if the current thread
97
98
has the global read lock and refuses the operation with
98
99
ER_CANT_UPDATE_WITH_READLOCK if applicable.
100
if (session.wait_if_global_read_lock(false, true))
101
if (session->wait_if_global_read_lock(false, true))
108
109
// @todo push this lock down into the engine
110
boost::mutex::scoped_lock scopedLock(session.catalog().schemaLock());
111
boost::mutex::scoped_lock scopedLock(LOCK_create_db);
112
113
// Check to see if it exists already.
113
identifier::Schema schema_identifier(schema_message.name());
114
SchemaIdentifier schema_identifier(schema_message.name());
114
115
if (plugin::StorageEngine::doesSchemaExist(schema_identifier))
116
117
if (not is_if_not_exists)
123
push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
124
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
124
125
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
125
126
schema_message.name().c_str());
129
130
else if (not plugin::StorageEngine::createSchema(schema_message)) // Try to create it
146
147
/* db-name is already validated when we come here */
148
bool alter(Session &session,
149
const message::Schema &schema_message,
150
const message::Schema &original_schema)
149
bool alter_db(Session *session, const message::Schema &schema_message)
152
151
TransactionServices &transaction_services= TransactionServices::singleton();
155
154
Do not alter database if another thread is holding read lock.
156
Wait for global read lock before acquiring session->catalog()->schemaLock().
155
Wait for global read lock before acquiring LOCK_create_db.
157
156
After wait_if_global_read_lock() we have protection against another
158
global read lock. If we would acquire session->catalog()->schemaLock() first,
157
global read lock. If we would acquire LOCK_create_db first,
159
158
another thread could step in and get the global read lock before we
160
159
reach wait_if_global_read_lock(). If this thread tries the same as we
161
(admin a db), it would then go and wait on session->catalog()->schemaLock()...
160
(admin a db), it would then go and wait on LOCK_create_db...
162
161
Furthermore wait_if_global_read_lock() checks if the current thread
163
162
has the global read lock and refuses the operation with
164
163
ER_CANT_UPDATE_WITH_READLOCK if applicable.
166
if ((session.wait_if_global_read_lock(false, true)))
165
if ((session->wait_if_global_read_lock(false, true)))
171
boost::mutex::scoped_lock scopedLock(session.catalog().schemaLock());
170
boost::mutex::scoped_lock scopedLock(LOCK_create_db);
173
identifier::Schema schema_idenifier(schema_message.name());
172
SchemaIdentifier schema_idenifier(schema_message.name());
174
173
if (not plugin::StorageEngine::doesSchemaExist(schema_idenifier))
176
175
my_error(ER_SCHEMA_DOES_NOT_EXIST, schema_idenifier);
185
transaction_services.alterSchema(session, original_schema, schema_message);
184
transaction_services.rawStatement(session, *session->getQueryString());
190
189
my_error(ER_ALTER_SCHEMA, schema_idenifier);
193
session.startWaitingGlobalReadLock();
192
session->startWaitingGlobalReadLock();
216
bool drop(Session &session, identifier::Schema &schema_identifier, const bool if_exists)
215
bool rm_db(Session *session, SchemaIdentifier &schema_identifier, const bool if_exists)
218
217
bool error= false;
221
220
Do not drop database if another thread is holding read lock.
222
Wait for global read lock before acquiring session->catalog()->schemaLock().
221
Wait for global read lock before acquiring LOCK_create_db.
223
222
After wait_if_global_read_lock() we have protection against another
224
global read lock. If we would acquire session->catalog()->schemaLock() first,
223
global read lock. If we would acquire LOCK_create_db first,
225
224
another thread could step in and get the global read lock before we
226
225
reach wait_if_global_read_lock(). If this thread tries the same as we
227
(admin a db), it would then go and wait on session->catalog()->schemaLock()...
226
(admin a db), it would then go and wait on LOCK_create_db...
228
227
Furthermore wait_if_global_read_lock() checks if the current thread
229
228
has the global read lock and refuses the operation with
230
229
ER_CANT_UPDATE_WITH_READLOCK if applicable.
232
if (session.wait_if_global_read_lock(false, true))
231
if (session->wait_if_global_read_lock(false, true))
239
boost::mutex::scoped_lock scopedLock(session.catalog().schemaLock());
240
message::schema::shared_ptr message= plugin::StorageEngine::getSchemaDefinition(schema_identifier);
238
boost::mutex::scoped_lock scopedLock(LOCK_create_db);
242
240
/* See if the schema exists */
241
if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
244
schema_identifier.getSQLPath(path);
248
schema_identifier.getSQLPath(path);
250
push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
248
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
251
249
ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
271
269
SELECT DATABASE() in the future). For this we free() session->db and set
274
if (not error and schema_identifier.compare(*session.schema()))
272
if (not error and schema_identifier.compare(*session->schema()))
275
273
change_db_impl(session);
277
session.startWaitingGlobalReadLock();
275
session->startWaitingGlobalReadLock();
341
339
@retval true Error
344
bool change(Session &session, identifier::Schema &schema_identifier)
342
bool change_db(Session *session, SchemaIdentifier &schema_identifier)
347
if (not plugin::Authorization::isAuthorized(*session.user(), schema_identifier))
345
if (not plugin::Authorization::isAuthorized(session->user(), schema_identifier))
349
347
/* Error message is set in isAuthorized */
353
if (not check(session, schema_identifier))
351
if (not check_db_name(session, schema_identifier))
354
schema_identifier.getSQLPath(path);
355
355
my_error(ER_WRONG_DB_NAME, schema_identifier);
382
382
@param new_db_charset Character set of the new database.
385
static void change_db_impl(Session &session, identifier::Schema &schema_identifier)
385
static void change_db_impl(Session *session, SchemaIdentifier &schema_identifier)
387
387
/* 1. Change current database in Session. */
405
405
the previous database name, we should do it explicitly.
408
session.set_db(schema_identifier.getSchemaName());
412
static void change_db_impl(Session &session)
414
session.set_db(string());
418
Check if database name is valid
422
org_name Name of database and length
429
bool check(Session &session, identifier::Schema &schema_identifier)
431
if (not plugin::Authorization::isAuthorized(*session.user(), schema_identifier))
436
return schema_identifier.isValid();
439
} /* namespace schema */
408
session->set_db(schema_identifier.getSchemaName());
412
static void change_db_impl(Session *session)
414
session->set_db(string());
441
417
} /* namespace drizzled */