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"
31
32
#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);
70
68
void Schema::prime()
72
CachedDirectory directory(drizzle_data_home, CachedDirectory::DIRECTORY);
70
CachedDirectory directory(getDataHomeCatalog().file_string(), CachedDirectory::DIRECTORY);
73
71
CachedDirectory::Entries files= directory.getEntries();
75
pthread_rwlock_wrlock(&schema_lock);
77
75
for (CachedDirectory::Entries::iterator fileIter= files.begin();
78
76
fileIter != files.end(); fileIter++)
80
78
CachedDirectory::Entry *entry= *fileIter;
81
79
message::Schema schema_message;
83
if (readSchemaFile(entry->filename, schema_message))
81
if (not entry->filename.compare(GLOBAL_TEMPORARY_EXT))
84
SchemaIdentifier filename(entry->filename);
85
if (readSchemaFile(filename, schema_message))
85
87
SchemaIdentifier schema_identifier(schema_message.name());
87
89
pair<SchemaCache::iterator, bool> ret=
88
schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
90
schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
90
92
if (ret.second == false)
96
pthread_rwlock_unlock(&schema_lock);
99
void Schema::doGetSchemaIdentifiers(SchemaIdentifierList &set_of_names)
101
void Schema::doGetSchemaIdentifiers(SchemaIdentifiers &set_of_names)
101
if (not pthread_rwlock_rdlock(&schema_lock))
103
105
for (SchemaCache::iterator iter= schema_cache.begin();
104
106
iter != schema_cache.end();
107
set_of_names.push_back(SchemaIdentifier((*iter).second.name()));
109
set_of_names.push_back(SchemaIdentifier((*iter).second->name()));
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);
112
mutex.unlock_shared();
128
bool Schema::doGetSchemaDefinition(SchemaIdentifier &schema_identifier, message::Schema &schema_message)
115
bool Schema::doGetSchemaDefinition(const SchemaIdentifier &schema_identifier, message::SchemaPtr &schema_message)
130
if (not pthread_rwlock_rdlock(&schema_lock))
118
SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
120
if (iter != schema_cache.end())
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);
122
schema_message= (*iter).second;
123
mutex.unlock_shared();
126
mutex.unlock_shared();
145
// Fail to disk based means
146
return readSchemaFile(schema_identifier.getPath(), schema_message);
149
132
bool Schema::doCreateSchema(const drizzled::message::Schema &schema_message)
151
134
SchemaIdentifier schema_identifier(schema_message.name());
163
if (not pthread_rwlock_wrlock(&schema_lock))
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);
148
pair<SchemaCache::iterator, bool> ret=
149
schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
152
if (ret.second == false)
154
abort(); // If this has happened, something really bad is going down.
179
bool Schema::doDropSchema(SchemaIdentifier &schema_identifier)
162
bool Schema::doDropSchema(const SchemaIdentifier &schema_identifier)
181
message::Schema schema_message;
164
message::SchemaPtr schema_message;
183
166
string schema_file(schema_identifier.getPath());
184
167
schema_file.append(1, FN_LIBCHAR);
228
209
if (writeSchemaFile(schema_identifier, schema_message))
230
if (not pthread_rwlock_wrlock(&schema_lock))
232
213
schema_cache.erase(schema_identifier.getPath());
234
215
pair<SchemaCache::iterator, bool> ret=
235
schema_cache.insert(make_pair(schema_identifier.getPath(), schema_message));
216
schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
237
218
if (ret.second == false)
239
220
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.
256
232
@note we do the rename to make it crash safe.
258
bool Schema::writeSchemaFile(SchemaIdentifier &schema_identifier, const message::Schema &db)
234
bool Schema::writeSchemaFile(const SchemaIdentifier &schema_identifier, const message::Schema &db)
260
236
char schema_file_tmp[FN_REFLEN];
261
237
string schema_file(schema_identifier.getPath());
278
if (not db.SerializeToFileDescriptor(fd))
280
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
281
db.InitializationErrorString().c_str());
257
success= db.SerializeToFileDescriptor(fd);
266
my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), schema_file.c_str(),
267
db.InitializationErrorString().empty() ? "unknown" : db.InitializationErrorString().c_str());
283
269
if (close(fd) == -1)
284
270
perror(schema_file_tmp);
314
bool Schema::readSchemaFile(const std::string &schema_file_name, drizzled::message::Schema &schema_message)
300
bool Schema::readSchemaFile(const drizzled::SchemaIdentifier &schema_identifier, drizzled::message::Schema &schema)
316
string db_opt_path(schema_file_name);
302
string db_opt_path(schema_identifier.getPath());
319
305
Pass an empty file name, and the database options file name as extension
332
318
if (input.good())
334
if (schema_message.ParseFromIstream(&input))
320
if (schema.ParseFromIstream(&input))
339
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
340
schema_message.InitializationErrorString().c_str());
325
my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), db_opt_path.c_str(),
326
schema.InitializationErrorString().empty() ? "unknown" : schema.InitializationErrorString().c_str());
350
bool Schema::doCanCreateTable(drizzled::TableIdentifier &identifier)
336
bool Schema::doCanCreateTable(const drizzled::TableIdentifier &identifier)
352
if (static_cast<SchemaIdentifier&>(identifier) == TEMPORARY_IDENTIFIER)
339
// This should always be the same value as GLOBAL_TEMPORARY_EXT but be
342
// This needs to be done static in here for ordering reasons
343
static SchemaIdentifier TEMPORARY_IDENTIFIER(".TEMPORARY");
344
if (static_cast<const SchemaIdentifier&>(identifier) == TEMPORARY_IDENTIFIER)
360
352
void Schema::doGetTableIdentifiers(drizzled::CachedDirectory&,
361
drizzled::SchemaIdentifier&,
353
const drizzled::SchemaIdentifier&,
362
354
drizzled::TableIdentifiers&)