27
27
#include "drizzled/charset.h"
28
28
#include "drizzled/charset_info.h"
29
29
#include "drizzled/cursor.h"
30
#include "drizzled/data_home.h"
32
31
#include "drizzled/internal/my_sys.h"
58
58
schema_cache_filled(false)
60
60
table_definition_ext= DEFAULT_FILE_EXTENSION;
61
pthread_rwlock_init(&schema_lock, NULL);
67
pthread_rwlock_destroy(&schema_lock);
67
70
void Schema::prime()
69
CachedDirectory directory(getDataHomeCatalog().file_string(), CachedDirectory::DIRECTORY);
72
CachedDirectory directory(drizzle_data_home, CachedDirectory::DIRECTORY);
70
73
CachedDirectory::Entries files= directory.getEntries();
75
pthread_rwlock_wrlock(&schema_lock);
74
77
for (CachedDirectory::Entries::iterator fileIter= files.begin();
75
78
fileIter != files.end(); fileIter++)
77
80
CachedDirectory::Entry *entry= *fileIter;
78
81
message::Schema schema_message;
80
if (not entry->filename.compare(GLOBAL_TEMPORARY_EXT))
83
SchemaIdentifier filename(entry->filename);
84
if (readSchemaFile(filename, schema_message))
83
if (readSchemaFile(entry->filename, schema_message))
86
85
SchemaIdentifier schema_identifier(schema_message.name());
88
87
pair<SchemaCache::iterator, bool> ret=
89
schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
88
schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
91
90
if (ret.second == false)
96
pthread_rwlock_unlock(&schema_lock);
100
void Schema::doGetSchemaIdentifiers(SchemaIdentifier::vector &set_of_names)
99
void Schema::doGetSchemaIdentifiers(SchemaIdentifierList &set_of_names)
101
if (not pthread_rwlock_rdlock(&schema_lock))
104
103
for (SchemaCache::iterator iter= schema_cache.begin();
105
104
iter != schema_cache.end();
108
set_of_names.push_back(SchemaIdentifier((*iter).second->name()));
107
set_of_names.push_back(SchemaIdentifier((*iter).second.name()));
111
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(drizzle_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);
114
bool Schema::doGetSchemaDefinition(const SchemaIdentifier &schema_identifier, message::schema::shared_ptr &schema_message)
128
bool Schema::doGetSchemaDefinition(SchemaIdentifier &schema_identifier, message::Schema &schema_message)
117
SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
119
if (iter != schema_cache.end())
130
if (not pthread_rwlock_rdlock(&schema_lock))
121
schema_message= (*iter).second;
122
mutex.unlock_shared();
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);
125
mutex.unlock_shared();
145
// Fail to disk based means
146
return readSchemaFile(schema_identifier.getPath(), schema_message);
131
149
bool Schema::doCreateSchema(const drizzled::message::Schema &schema_message)
133
151
SchemaIdentifier schema_identifier(schema_message.name());
163
if (not pthread_rwlock_wrlock(&schema_lock))
147
pair<SchemaCache::iterator, bool> ret=
148
schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
151
if (ret.second == false)
153
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);
161
bool Schema::doDropSchema(const SchemaIdentifier &schema_identifier)
179
bool Schema::doDropSchema(SchemaIdentifier &schema_identifier)
163
message::schema::shared_ptr schema_message;
181
message::Schema schema_message;
165
183
string schema_file(schema_identifier.getPath());
166
184
schema_file.append(1, FN_LIBCHAR);
208
228
if (writeSchemaFile(schema_identifier, schema_message))
230
if (not pthread_rwlock_wrlock(&schema_lock))
212
232
schema_cache.erase(schema_identifier.getPath());
214
234
pair<SchemaCache::iterator, bool> ret=
215
schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
235
schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
217
237
if (ret.second == false)
219
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.
231
256
@note we do the rename to make it crash safe.
233
bool Schema::writeSchemaFile(const SchemaIdentifier &schema_identifier, const message::Schema &db)
258
bool Schema::writeSchemaFile(SchemaIdentifier &schema_identifier, const message::Schema &db)
235
260
char schema_file_tmp[FN_REFLEN];
236
261
string schema_file(schema_identifier.getPath());
256
success= db.SerializeToFileDescriptor(fd);
265
my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), schema_file.c_str(),
266
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());
268
283
if (close(fd) == -1)
269
284
perror(schema_file_tmp);
299
bool Schema::readSchemaFile(const drizzled::SchemaIdentifier &schema_identifier, drizzled::message::Schema &schema)
314
bool Schema::readSchemaFile(const std::string &schema_file_name, drizzled::message::Schema &schema_message)
301
string db_opt_path(schema_identifier.getPath());
316
string db_opt_path(schema_file_name);
304
319
Pass an empty file name, and the database options file name as extension
317
332
if (input.good())
319
if (schema.ParseFromIstream(&input))
334
if (schema_message.ParseFromIstream(&input))
324
my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), db_opt_path.c_str(),
325
schema.InitializationErrorString().empty() ? "unknown" : schema.InitializationErrorString().c_str());
339
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
340
schema_message.InitializationErrorString().c_str());
350
bool Schema::doCanCreateTable(drizzled::TableIdentifier &identifier)
352
if (static_cast<SchemaIdentifier&>(identifier) == TEMPORARY_IDENTIFIER)
335
360
void Schema::doGetTableIdentifiers(drizzled::CachedDirectory&,
336
const drizzled::SchemaIdentifier&,
337
drizzled::TableIdentifier::vector&)
361
drizzled::SchemaIdentifier&,
362
drizzled::TableIdentifiers&)