18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
#include <plugin/schema_engine/schema.h>
24
#include <drizzled/schema.h>
25
#include <drizzled/sql_table.h>
26
#include <drizzled/global_charset_info.h>
27
#include <drizzled/charset.h>
28
#include <drizzled/charset_info.h>
29
#include <drizzled/cursor.h>
30
#include <drizzled/data_home.h>
32
#include <drizzled/pthread_globals.h>
34
#include <drizzled/execute.h>
36
#include <drizzled/internal/my_sys.h>
23
#include "plugin/schema_engine/schema.h"
24
#include "drizzled/db.h"
25
#include "drizzled/sql_table.h"
26
#include "drizzled/global_charset_info.h"
27
#include "drizzled/charset.h"
28
#include "drizzled/charset_info.h"
29
#include "drizzled/cursor.h"
31
#include "drizzled/internal/my_sys.h"
39
34
#include <sys/stat.h>
62
58
schema_cache_filled(false)
64
60
table_definition_ext= DEFAULT_FILE_EXTENSION;
61
pthread_rwlock_init(&schema_lock, NULL);
67
pthread_rwlock_destroy(&schema_lock);
71
70
void Schema::prime()
73
CachedDirectory directory(getDataHomeCatalog().file_string(), CachedDirectory::DIRECTORY);
72
CachedDirectory directory(data_home, CachedDirectory::DIRECTORY);
74
73
CachedDirectory::Entries files= directory.getEntries();
75
boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
75
pthread_rwlock_wrlock(&schema_lock);
77
77
for (CachedDirectory::Entries::iterator fileIter= files.begin();
78
78
fileIter != files.end(); fileIter++)
80
80
CachedDirectory::Entry *entry= *fileIter;
81
81
message::Schema schema_message;
83
if (not entry->filename.compare(GLOBAL_TEMPORARY_EXT))
86
83
if (readSchemaFile(entry->filename, schema_message))
88
identifier::Schema schema_identifier(schema_message.name());
85
SchemaIdentifier schema_identifier(schema_message.name());
90
87
pair<SchemaCache::iterator, bool> ret=
91
schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
88
schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
93
90
if (ret.second == false)
95
92
abort(); // If this has happened, something really bad is going down.
101
void Schema::startup(drizzled::Session &)
105
void Schema::doGetSchemaIdentifiers(identifier::Schema::vector &set_of_names)
96
pthread_rwlock_unlock(&schema_lock);
99
void Schema::doGetSchemaIdentifiers(SchemaIdentifierList &set_of_names)
101
if (not pthread_rwlock_rdlock(&schema_lock))
109
103
for (SchemaCache::iterator iter= schema_cache.begin();
110
104
iter != schema_cache.end();
113
set_of_names.push_back(identifier::Schema((*iter).second->name()));
107
set_of_names.push_back(SchemaIdentifier((*iter).second.name()));
116
mutex.unlock_shared();
109
pthread_rwlock_unlock(&schema_lock);
114
// If for some reason getting a lock should fail, we resort to disk
116
CachedDirectory directory(data_home, CachedDirectory::DIRECTORY);
118
CachedDirectory::Entries files= directory.getEntries();
120
for (CachedDirectory::Entries::iterator fileIter= files.begin();
121
fileIter != files.end(); fileIter++)
123
CachedDirectory::Entry *entry= *fileIter;
124
set_of_names.push_back(entry->filename);
119
drizzled::message::schema::shared_ptr Schema::doGetSchemaDefinition(const identifier::Schema &schema_identifier)
128
bool Schema::doGetSchemaDefinition(SchemaIdentifier &schema_identifier, message::Schema &schema_message)
122
SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
124
if (iter != schema_cache.end())
130
if (not pthread_rwlock_rdlock(&schema_lock))
126
drizzled::message::schema::shared_ptr schema_message;
127
schema_message= (*iter).second;
128
mutex.unlock_shared();
130
return schema_message;
132
SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
134
if (iter != schema_cache.end())
136
schema_message.CopyFrom(((*iter).second));
137
pthread_rwlock_unlock(&schema_lock);
140
pthread_rwlock_unlock(&schema_lock);
132
mutex.unlock_shared();
134
return drizzled::message::schema::shared_ptr();
145
// Fail to disk based means
146
return readSchemaFile(schema_identifier.getPath(), schema_message);
138
149
bool Schema::doCreateSchema(const drizzled::message::Schema &schema_message)
140
identifier::Schema schema_identifier(schema_message.name());
151
SchemaIdentifier schema_identifier(schema_message.name());
142
153
if (mkdir(schema_identifier.getPath().c_str(), 0777) == -1)
144
sql_perror(schema_identifier.getPath().c_str());
148
156
if (not writeSchemaFile(schema_identifier, schema_message))
163
if (not pthread_rwlock_wrlock(&schema_lock))
156
boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
157
pair<SchemaCache::iterator, bool> ret=
158
schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
161
if (ret.second == false)
163
abort(); // If this has happened, something really bad is going down.
165
pair<SchemaCache::iterator, bool> ret=
166
schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
169
if (ret.second == false)
171
abort(); // If this has happened, something really bad is going down.
173
pthread_rwlock_unlock(&schema_lock);
170
bool Schema::doDropSchema(const identifier::Schema &schema_identifier)
179
bool Schema::doDropSchema(SchemaIdentifier &schema_identifier)
181
message::Schema schema_message;
172
183
string schema_file(schema_identifier.getPath());
173
184
schema_file.append(1, FN_LIBCHAR);
174
185
schema_file.append(MY_DB_OPT_FILE);
176
if (not doGetSchemaDefinition(schema_identifier))
187
if (not doGetSchemaDefinition(schema_identifier, schema_message))
179
190
// No db.opt file, no love from us.
180
191
if (access(schema_file.c_str(), F_OK))
182
sql_perror(schema_file.c_str());
193
perror(schema_file.c_str());
186
197
if (unlink(schema_file.c_str()))
188
sql_perror(schema_file.c_str());
199
perror(schema_file.c_str());
192
203
if (rmdir(schema_identifier.getPath().c_str()))
194
sql_perror(schema_identifier.getPath().c_str());
205
perror(schema_identifier.getPath().c_str());
195
206
//@todo If this happens, we want a report of it. For the moment I dump
196
207
//to stderr so I can catch it in Hudson.
197
208
CachedDirectory dir(schema_identifier.getPath());
201
boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
202
schema_cache.erase(schema_identifier.getPath());
212
if (not pthread_rwlock_wrlock(&schema_lock))
214
schema_cache.erase(schema_identifier.getPath());
215
pthread_rwlock_unlock(&schema_lock);
207
221
bool Schema::doAlterSchema(const drizzled::message::Schema &schema_message)
209
identifier::Schema schema_identifier(schema_message.name());
223
SchemaIdentifier schema_identifier(schema_message.name());
211
225
if (access(schema_identifier.getPath().c_str(), F_OK))
214
228
if (writeSchemaFile(schema_identifier, schema_message))
216
boost::unique_lock<boost::shared_mutex> scopedLock(mutex);
217
schema_cache.erase(schema_identifier.getPath());
219
pair<SchemaCache::iterator, bool> ret=
220
schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
222
if (ret.second == false)
224
abort(); // If this has happened, something really bad is going down.
230
if (not pthread_rwlock_wrlock(&schema_lock))
232
schema_cache.erase(schema_identifier.getPath());
234
pair<SchemaCache::iterator, bool> ret=
235
schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
237
if (ret.second == false)
239
abort(); // If this has happened, something really bad is going down.
242
pthread_rwlock_unlock(&schema_lock);
246
abort(); // This would leave us out of sync, suck.
251
sql_perror(schema_file_tmp);
273
perror(schema_file_tmp);
259
success= db.SerializeToFileDescriptor(fd);
268
my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), schema_file.c_str(),
269
db.InitializationErrorString().empty() ? "unknown" : db.InitializationErrorString().c_str());
278
if (not db.SerializeToFileDescriptor(fd))
280
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
281
db.InitializationErrorString().c_str());
271
283
if (close(fd) == -1)
272
sql_perror(schema_file_tmp);
284
perror(schema_file_tmp);
274
286
if (unlink(schema_file_tmp))
275
sql_perror(schema_file_tmp);
287
perror(schema_file_tmp);
280
292
if (close(fd) == -1)
282
sql_perror(schema_file_tmp);
294
perror(schema_file_tmp);
284
296
if (unlink(schema_file_tmp))
285
sql_perror(schema_file_tmp);
297
perror(schema_file_tmp);
302
bool Schema::readSchemaFile(const drizzled::identifier::Schema &schema_identifier, drizzled::message::Schema &schema)
314
bool Schema::readSchemaFile(const std::string &schema_file_name, drizzled::message::Schema &schema_message)
304
return readSchemaFile(schema_identifier.getPath(), schema);
316
string db_opt_path(schema_file_name);
307
bool Schema::readSchemaFile(std::string db_opt_path, drizzled::message::Schema &schema)
310
319
Pass an empty file name, and the database options file name as extension
311
320
to avoid table name to file name encoding.
323
332
if (input.good())
325
if (schema.ParseFromIstream(&input))
334
if (schema_message.ParseFromIstream(&input))
330
my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), db_opt_path.c_str(),
331
schema.InitializationErrorString().empty() ? "unknown" : schema.InitializationErrorString().c_str());
339
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
340
schema_message.InitializationErrorString().c_str());
335
sql_perror(db_opt_path.c_str());
344
perror(db_opt_path.c_str());
350
bool Schema::doCanCreateTable(drizzled::TableIdentifier &identifier)
352
if (static_cast<SchemaIdentifier&>(identifier) == TEMPORARY_IDENTIFIER)
341
360
void Schema::doGetTableIdentifiers(drizzled::CachedDirectory&,
342
const drizzled::identifier::Schema&,
343
drizzled::identifier::Table::vector&)
361
drizzled::SchemaIdentifier&,
362
drizzled::TableIdentifiers&)